Use authentication token from config for communication with Nomad

This commit is contained in:
Jan-Eric Hellenberg
2021-07-26 11:41:30 +02:00
committed by Jan-Eric Hellenberg
parent 23b726cef9
commit 3aa1227db6
7 changed files with 58 additions and 46 deletions

View File

@ -16,7 +16,7 @@ var (
// apiQuerier provides access to the Nomad functionality.
type apiQuerier interface {
// init prepares an apiClient to be able to communicate to a provided Nomad API.
init(nomadURL *url.URL, nomadNamespace string) (err error)
init(nomadURL *url.URL, nomadNamespace, nomadToken string) (err error)
// LoadJobList loads the list of jobs from the Nomad API.
LoadJobList() (list []*nomadApi.JobListStub, err error)
@ -61,11 +61,12 @@ type nomadAPIClient struct {
namespace string
}
func (nc *nomadAPIClient) init(nomadURL *url.URL, nomadNamespace string) (err error) {
func (nc *nomadAPIClient) init(nomadURL *url.URL, nomadNamespace, nomadToken string) (err error) {
nc.client, err = nomadApi.NewClient(&nomadApi.Config{
Address: nomadURL.String(),
TLSConfig: &nomadApi.TLSConfig{},
Namespace: nomadNamespace,
SecretID: nomadToken,
})
if err != nil {
return fmt.Errorf("error creating new Nomad client: %w", err)
@ -146,7 +147,13 @@ func (nc *nomadAPIClient) AllocationStream(ctx context.Context) (<-chan *nomadAp
stream, err := nc.client.EventStream().Stream(
ctx,
map[nomadApi.Topic][]string{
nomadApi.TopicAllocation: {},
nomadApi.TopicAllocation: {
// Necessary to have the "topic" URL param show up in the HTTP request to Nomad.
// Without the param, Nomad will try to deliver all event types.
// However, this includes some events that require a management authentication token.
// As Poseidon uses no such token, the request will return a permission denied error.
"*",
},
},
0,
nc.queryOptions())

View File

@ -42,13 +42,13 @@ func (_m *apiQuerierMock) AllocationStream(ctx context.Context) (<-chan *api.Eve
return r0, r1
}
// DeleteRunner provides a mock function with given fields: runnerId
func (_m *apiQuerierMock) DeleteRunner(runnerId string) error {
ret := _m.Called(runnerId)
// DeleteRunner provides a mock function with given fields: runnerID
func (_m *apiQuerierMock) DeleteRunner(runnerID string) error {
ret := _m.Called(runnerID)
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(runnerId)
r0 = rf(runnerID)
} else {
r0 = ret.Error(0)
}
@ -101,19 +101,19 @@ func (_m *apiQuerierMock) Execute(jobID string, ctx context.Context, command []s
}
// JobScale provides a mock function with given fields: jobID
func (_m *apiQuerierMock) JobScale(jobId string) (uint, error) {
ret := _m.Called(jobId)
func (_m *apiQuerierMock) JobScale(jobID string) (uint, error) {
ret := _m.Called(jobID)
var r0 uint
if rf, ok := ret.Get(0).(func(string) uint); ok {
r0 = rf(jobId)
r0 = rf(jobID)
} else {
r0 = ret.Get(0).(uint)
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(jobId)
r1 = rf(jobID)
} else {
r1 = ret.Error(1)
}
@ -166,12 +166,12 @@ func (_m *apiQuerierMock) RegisterNomadJob(job *api.Job) (string, error) {
}
// SetJobScale provides a mock function with given fields: jobID, count, reason
func (_m *apiQuerierMock) SetJobScale(jobId string, count uint, reason string) error {
ret := _m.Called(jobId, count, reason)
func (_m *apiQuerierMock) SetJobScale(jobID string, count uint, reason string) error {
ret := _m.Called(jobID, count, reason)
var r0 error
if rf, ok := ret.Get(0).(func(string, uint, string) error); ok {
r0 = rf(jobId, count, reason)
r0 = rf(jobID, count, reason)
} else {
r0 = ret.Error(0)
}
@ -202,13 +202,13 @@ func (_m *apiQuerierMock) allocation(jobID string) (*api.Allocation, error) {
return r0, r1
}
// init provides a mock function with given fields: nomadURL, nomadNamespace
func (_m *apiQuerierMock) init(nomadURL *url.URL, nomadNamespace string) error {
ret := _m.Called(nomadURL, nomadNamespace)
// init provides a mock function with given fields: nomadURL, nomadNamespace, nomadToken
func (_m *apiQuerierMock) init(nomadURL *url.URL, nomadNamespace string, nomadToken string) error {
ret := _m.Called(nomadURL, nomadNamespace, nomadToken)
var r0 error
if rf, ok := ret.Get(0).(func(*url.URL, string) error); ok {
r0 = rf(nomadURL, nomadNamespace)
if rf, ok := ret.Get(0).(func(*url.URL, string, string) error); ok {
r0 = rf(nomadURL, nomadNamespace, nomadToken)
} else {
r0 = ret.Error(0)
}

View File

@ -42,13 +42,13 @@ func (_m *ExecutorAPIMock) AllocationStream(ctx context.Context) (<-chan *api.Ev
return r0, r1
}
// DeleteRunner provides a mock function with given fields: runnerId
func (_m *ExecutorAPIMock) DeleteRunner(runnerId string) error {
ret := _m.Called(runnerId)
// DeleteRunner provides a mock function with given fields: runnerID
func (_m *ExecutorAPIMock) DeleteRunner(runnerID string) error {
ret := _m.Called(runnerID)
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(runnerId)
r0 = rf(runnerID)
} else {
r0 = ret.Error(0)
}
@ -122,19 +122,19 @@ func (_m *ExecutorAPIMock) ExecuteCommand(allocationID string, ctx context.Conte
}
// JobScale provides a mock function with given fields: jobID
func (_m *ExecutorAPIMock) JobScale(jobId string) (uint, error) {
ret := _m.Called(jobId)
func (_m *ExecutorAPIMock) JobScale(jobID string) (uint, error) {
ret := _m.Called(jobID)
var r0 uint
if rf, ok := ret.Get(0).(func(string) uint); ok {
r0 = rf(jobId)
r0 = rf(jobID)
} else {
r0 = ret.Get(0).(uint)
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(jobId)
r1 = rf(jobID)
} else {
r1 = ret.Error(1)
}
@ -234,7 +234,7 @@ func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID string) ([]*api.Job, err
return r0, r1
}
// LoadRunnerPorts provides a mock function with given fields: runnerID
// LoadRunnerPortMappings provides a mock function with given fields: runnerID
func (_m *ExecutorAPIMock) LoadRunnerPortMappings(runnerID string) ([]api.PortMapping, error) {
ret := _m.Called(runnerID)
@ -344,12 +344,12 @@ func (_m *ExecutorAPIMock) RegisterTemplateJob(defaultJob *api.Job, id string, p
}
// SetJobScale provides a mock function with given fields: jobID, count, reason
func (_m *ExecutorAPIMock) SetJobScale(jobId string, count uint, reason string) error {
ret := _m.Called(jobId, count, reason)
func (_m *ExecutorAPIMock) SetJobScale(jobID string, count uint, reason string) error {
ret := _m.Called(jobID, count, reason)
var r0 error
if rf, ok := ret.Get(0).(func(string, uint, string) error); ok {
r0 = rf(jobId, count, reason)
r0 = rf(jobID, count, reason)
} else {
r0 = ret.Error(0)
}
@ -394,13 +394,13 @@ func (_m *ExecutorAPIMock) allocation(jobID string) (*api.Allocation, error) {
return r0, r1
}
// init provides a mock function with given fields: nomadURL, nomadNamespace
func (_m *ExecutorAPIMock) init(nomadURL *url.URL, nomadNamespace string) error {
ret := _m.Called(nomadURL, nomadNamespace)
// init provides a mock function with given fields: nomadURL, nomadNamespace, nomadToken
func (_m *ExecutorAPIMock) init(nomadURL *url.URL, nomadNamespace string, nomadToken string) error {
ret := _m.Called(nomadURL, nomadNamespace, nomadToken)
var r0 error
if rf, ok := ret.Get(0).(func(*url.URL, string) error); ok {
r0 = rf(nomadURL, nomadNamespace)
if rf, ok := ret.Get(0).(func(*url.URL, string, string) error); ok {
r0 = rf(nomadURL, nomadNamespace, nomadToken)
} else {
r0 = ret.Error(0)
}

View File

@ -81,15 +81,15 @@ type APIClient struct {
// NewExecutorAPI creates a new api client.
// One client is usually sufficient for the complete runtime of the API.
func NewExecutorAPI(nomadURL *url.URL, nomadNamespace string) (ExecutorAPI, error) {
func NewExecutorAPI(nomadURL *url.URL, nomadNamespace, nomadToken string) (ExecutorAPI, error) {
client := &APIClient{apiQuerier: &nomadAPIClient{}}
err := client.init(nomadURL, nomadNamespace)
err := client.init(nomadURL, nomadNamespace, nomadToken)
return client, err
}
// init prepares an apiClient to be able to communicate to a provided Nomad API.
func (a *APIClient) init(nomadURL *url.URL, nomadNamespace string) error {
if err := a.apiQuerier.init(nomadURL, nomadNamespace); err != nil {
func (a *APIClient) init(nomadURL *url.URL, nomadNamespace, nomadToken string) error {
if err := a.apiQuerier.init(nomadURL, nomadNamespace, nomadToken); err != nil {
return fmt.Errorf("error initializing API querier: %w", err)
}
return nil

View File

@ -130,10 +130,11 @@ var (
)
const TestNamespace = "unit-tests"
const TestNomadToken = "n0m4d-t0k3n"
func TestApiClient_init(t *testing.T) {
client := &APIClient{apiQuerier: &nomadAPIClient{}}
err := client.init(&TestURL, TestNamespace)
err := client.init(&TestURL, TestNamespace, TestNomadToken)
require.Nil(t, err)
}
@ -142,16 +143,16 @@ func TestApiClientCanNotBeInitializedWithInvalidUrl(t *testing.T) {
err := client.init(&url.URL{
Scheme: "http",
Host: "http://127.0.0.1:4646",
}, TestNamespace)
}, TestNamespace, TestNomadToken)
assert.NotNil(t, err)
}
func TestNewExecutorApiCanBeCreatedWithoutError(t *testing.T) {
expectedClient := &APIClient{apiQuerier: &nomadAPIClient{}}
err := expectedClient.init(&TestURL, TestNamespace)
err := expectedClient.init(&TestURL, TestNamespace, TestNomadToken)
require.Nil(t, err)
_, err = NewExecutorAPI(&TestURL, TestNamespace)
_, err = NewExecutorAPI(&TestURL, TestNamespace, TestNomadToken)
require.Nil(t, err)
}