Use authentication token from config for communication with Nomad
This commit is contained in:

committed by
Jan-Eric Hellenberg

parent
23b726cef9
commit
3aa1227db6
2
Makefile
2
Makefile
@ -51,7 +51,7 @@ golangci-lint: ## Lint the source code using golangci-lint
|
|||||||
lint: golangci-lint ## Lint the source code using all linters
|
lint: golangci-lint ## Lint the source code using all linters
|
||||||
|
|
||||||
.PHONY: mock
|
.PHONY: mock
|
||||||
snaked_name=$(shell sed -e "s/\([A-Z]\)/_\L\1/g" -e "s/^_//" <<< "$(name)")
|
snaked_name=$(shell sed -e "s/\([a-z]\)\([A-Z]\)/\1_\2/g" -e "s/\([A-Z]\)/\L\1/g" -e "s/^_//" <<< "$(name)")
|
||||||
mock: deps ## Create/Update a mock. Example: make mock name=apiQuerier pkg=./nomad
|
mock: deps ## Create/Update a mock. Example: make mock name=apiQuerier pkg=./nomad
|
||||||
@mockery \
|
@mockery \
|
||||||
--name=$(name) \
|
--name=$(name) \
|
||||||
|
@ -45,7 +45,11 @@ func runServer(server *http.Server) {
|
|||||||
|
|
||||||
func initServer() *http.Server {
|
func initServer() *http.Server {
|
||||||
// API initialization
|
// API initialization
|
||||||
nomadAPIClient, err := nomad.NewExecutorAPI(config.Config.NomadAPIURL(), config.Config.Nomad.Namespace)
|
nomadAPIClient, err := nomad.NewExecutorAPI(
|
||||||
|
config.Config.NomadAPIURL(),
|
||||||
|
config.Config.Nomad.Namespace,
|
||||||
|
config.Config.Nomad.Token,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).WithField("nomad url", config.Config.NomadAPIURL()).Fatal("Error parsing the nomad url")
|
log.WithError(err).WithField("nomad url", config.Config.NomadAPIURL()).Fatal("Error parsing the nomad url")
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ var (
|
|||||||
// apiQuerier provides access to the Nomad functionality.
|
// apiQuerier provides access to the Nomad functionality.
|
||||||
type apiQuerier interface {
|
type apiQuerier interface {
|
||||||
// init prepares an apiClient to be able to communicate to a provided Nomad API.
|
// 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 loads the list of jobs from the Nomad API.
|
||||||
LoadJobList() (list []*nomadApi.JobListStub, err error)
|
LoadJobList() (list []*nomadApi.JobListStub, err error)
|
||||||
@ -61,11 +61,12 @@ type nomadAPIClient struct {
|
|||||||
namespace string
|
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{
|
nc.client, err = nomadApi.NewClient(&nomadApi.Config{
|
||||||
Address: nomadURL.String(),
|
Address: nomadURL.String(),
|
||||||
TLSConfig: &nomadApi.TLSConfig{},
|
TLSConfig: &nomadApi.TLSConfig{},
|
||||||
Namespace: nomadNamespace,
|
Namespace: nomadNamespace,
|
||||||
|
SecretID: nomadToken,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error creating new Nomad client: %w", err)
|
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(
|
stream, err := nc.client.EventStream().Stream(
|
||||||
ctx,
|
ctx,
|
||||||
map[nomadApi.Topic][]string{
|
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,
|
0,
|
||||||
nc.queryOptions())
|
nc.queryOptions())
|
||||||
|
@ -42,13 +42,13 @@ func (_m *apiQuerierMock) AllocationStream(ctx context.Context) (<-chan *api.Eve
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteRunner provides a mock function with given fields: runnerId
|
// DeleteRunner provides a mock function with given fields: runnerID
|
||||||
func (_m *apiQuerierMock) DeleteRunner(runnerId string) error {
|
func (_m *apiQuerierMock) DeleteRunner(runnerID string) error {
|
||||||
ret := _m.Called(runnerId)
|
ret := _m.Called(runnerID)
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||||
r0 = rf(runnerId)
|
r0 = rf(runnerID)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Error(0)
|
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
|
// JobScale provides a mock function with given fields: jobID
|
||||||
func (_m *apiQuerierMock) JobScale(jobId string) (uint, error) {
|
func (_m *apiQuerierMock) JobScale(jobID string) (uint, error) {
|
||||||
ret := _m.Called(jobId)
|
ret := _m.Called(jobID)
|
||||||
|
|
||||||
var r0 uint
|
var r0 uint
|
||||||
if rf, ok := ret.Get(0).(func(string) uint); ok {
|
if rf, ok := ret.Get(0).(func(string) uint); ok {
|
||||||
r0 = rf(jobId)
|
r0 = rf(jobID)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Get(0).(uint)
|
r0 = ret.Get(0).(uint)
|
||||||
}
|
}
|
||||||
|
|
||||||
var r1 error
|
var r1 error
|
||||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||||
r1 = rf(jobId)
|
r1 = rf(jobID)
|
||||||
} else {
|
} else {
|
||||||
r1 = ret.Error(1)
|
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
|
// SetJobScale provides a mock function with given fields: jobID, count, reason
|
||||||
func (_m *apiQuerierMock) SetJobScale(jobId string, count uint, reason string) error {
|
func (_m *apiQuerierMock) SetJobScale(jobID string, count uint, reason string) error {
|
||||||
ret := _m.Called(jobId, count, reason)
|
ret := _m.Called(jobID, count, reason)
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
if rf, ok := ret.Get(0).(func(string, uint, string) error); ok {
|
if rf, ok := ret.Get(0).(func(string, uint, string) error); ok {
|
||||||
r0 = rf(jobId, count, reason)
|
r0 = rf(jobID, count, reason)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Error(0)
|
r0 = ret.Error(0)
|
||||||
}
|
}
|
||||||
@ -202,13 +202,13 @@ func (_m *apiQuerierMock) allocation(jobID string) (*api.Allocation, error) {
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// init provides a mock function with given fields: nomadURL, nomadNamespace
|
// init provides a mock function with given fields: nomadURL, nomadNamespace, nomadToken
|
||||||
func (_m *apiQuerierMock) init(nomadURL *url.URL, nomadNamespace string) error {
|
func (_m *apiQuerierMock) init(nomadURL *url.URL, nomadNamespace string, nomadToken string) error {
|
||||||
ret := _m.Called(nomadURL, nomadNamespace)
|
ret := _m.Called(nomadURL, nomadNamespace, nomadToken)
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
if rf, ok := ret.Get(0).(func(*url.URL, string) error); ok {
|
if rf, ok := ret.Get(0).(func(*url.URL, string, string) error); ok {
|
||||||
r0 = rf(nomadURL, nomadNamespace)
|
r0 = rf(nomadURL, nomadNamespace, nomadToken)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Error(0)
|
r0 = ret.Error(0)
|
||||||
}
|
}
|
||||||
|
@ -42,13 +42,13 @@ func (_m *ExecutorAPIMock) AllocationStream(ctx context.Context) (<-chan *api.Ev
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteRunner provides a mock function with given fields: runnerId
|
// DeleteRunner provides a mock function with given fields: runnerID
|
||||||
func (_m *ExecutorAPIMock) DeleteRunner(runnerId string) error {
|
func (_m *ExecutorAPIMock) DeleteRunner(runnerID string) error {
|
||||||
ret := _m.Called(runnerId)
|
ret := _m.Called(runnerID)
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||||
r0 = rf(runnerId)
|
r0 = rf(runnerID)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Error(0)
|
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
|
// JobScale provides a mock function with given fields: jobID
|
||||||
func (_m *ExecutorAPIMock) JobScale(jobId string) (uint, error) {
|
func (_m *ExecutorAPIMock) JobScale(jobID string) (uint, error) {
|
||||||
ret := _m.Called(jobId)
|
ret := _m.Called(jobID)
|
||||||
|
|
||||||
var r0 uint
|
var r0 uint
|
||||||
if rf, ok := ret.Get(0).(func(string) uint); ok {
|
if rf, ok := ret.Get(0).(func(string) uint); ok {
|
||||||
r0 = rf(jobId)
|
r0 = rf(jobID)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Get(0).(uint)
|
r0 = ret.Get(0).(uint)
|
||||||
}
|
}
|
||||||
|
|
||||||
var r1 error
|
var r1 error
|
||||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||||
r1 = rf(jobId)
|
r1 = rf(jobID)
|
||||||
} else {
|
} else {
|
||||||
r1 = ret.Error(1)
|
r1 = ret.Error(1)
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID string) ([]*api.Job, err
|
|||||||
return r0, r1
|
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) {
|
func (_m *ExecutorAPIMock) LoadRunnerPortMappings(runnerID string) ([]api.PortMapping, error) {
|
||||||
ret := _m.Called(runnerID)
|
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
|
// SetJobScale provides a mock function with given fields: jobID, count, reason
|
||||||
func (_m *ExecutorAPIMock) SetJobScale(jobId string, count uint, reason string) error {
|
func (_m *ExecutorAPIMock) SetJobScale(jobID string, count uint, reason string) error {
|
||||||
ret := _m.Called(jobId, count, reason)
|
ret := _m.Called(jobID, count, reason)
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
if rf, ok := ret.Get(0).(func(string, uint, string) error); ok {
|
if rf, ok := ret.Get(0).(func(string, uint, string) error); ok {
|
||||||
r0 = rf(jobId, count, reason)
|
r0 = rf(jobID, count, reason)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Error(0)
|
r0 = ret.Error(0)
|
||||||
}
|
}
|
||||||
@ -394,13 +394,13 @@ func (_m *ExecutorAPIMock) allocation(jobID string) (*api.Allocation, error) {
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// init provides a mock function with given fields: nomadURL, nomadNamespace
|
// init provides a mock function with given fields: nomadURL, nomadNamespace, nomadToken
|
||||||
func (_m *ExecutorAPIMock) init(nomadURL *url.URL, nomadNamespace string) error {
|
func (_m *ExecutorAPIMock) init(nomadURL *url.URL, nomadNamespace string, nomadToken string) error {
|
||||||
ret := _m.Called(nomadURL, nomadNamespace)
|
ret := _m.Called(nomadURL, nomadNamespace, nomadToken)
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
if rf, ok := ret.Get(0).(func(*url.URL, string) error); ok {
|
if rf, ok := ret.Get(0).(func(*url.URL, string, string) error); ok {
|
||||||
r0 = rf(nomadURL, nomadNamespace)
|
r0 = rf(nomadURL, nomadNamespace, nomadToken)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Error(0)
|
r0 = ret.Error(0)
|
||||||
}
|
}
|
||||||
|
@ -81,15 +81,15 @@ type APIClient struct {
|
|||||||
|
|
||||||
// NewExecutorAPI creates a new api client.
|
// NewExecutorAPI creates a new api client.
|
||||||
// One client is usually sufficient for the complete runtime of the API.
|
// 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{}}
|
client := &APIClient{apiQuerier: &nomadAPIClient{}}
|
||||||
err := client.init(nomadURL, nomadNamespace)
|
err := client.init(nomadURL, nomadNamespace, nomadToken)
|
||||||
return client, err
|
return client, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// init prepares an apiClient to be able to communicate to a provided Nomad API.
|
// init prepares an apiClient to be able to communicate to a provided Nomad API.
|
||||||
func (a *APIClient) init(nomadURL *url.URL, nomadNamespace string) error {
|
func (a *APIClient) init(nomadURL *url.URL, nomadNamespace, nomadToken string) error {
|
||||||
if err := a.apiQuerier.init(nomadURL, nomadNamespace); err != nil {
|
if err := a.apiQuerier.init(nomadURL, nomadNamespace, nomadToken); err != nil {
|
||||||
return fmt.Errorf("error initializing API querier: %w", err)
|
return fmt.Errorf("error initializing API querier: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -130,10 +130,11 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const TestNamespace = "unit-tests"
|
const TestNamespace = "unit-tests"
|
||||||
|
const TestNomadToken = "n0m4d-t0k3n"
|
||||||
|
|
||||||
func TestApiClient_init(t *testing.T) {
|
func TestApiClient_init(t *testing.T) {
|
||||||
client := &APIClient{apiQuerier: &nomadAPIClient{}}
|
client := &APIClient{apiQuerier: &nomadAPIClient{}}
|
||||||
err := client.init(&TestURL, TestNamespace)
|
err := client.init(&TestURL, TestNamespace, TestNomadToken)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,16 +143,16 @@ func TestApiClientCanNotBeInitializedWithInvalidUrl(t *testing.T) {
|
|||||||
err := client.init(&url.URL{
|
err := client.init(&url.URL{
|
||||||
Scheme: "http",
|
Scheme: "http",
|
||||||
Host: "http://127.0.0.1:4646",
|
Host: "http://127.0.0.1:4646",
|
||||||
}, TestNamespace)
|
}, TestNamespace, TestNomadToken)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewExecutorApiCanBeCreatedWithoutError(t *testing.T) {
|
func TestNewExecutorApiCanBeCreatedWithoutError(t *testing.T) {
|
||||||
expectedClient := &APIClient{apiQuerier: &nomadAPIClient{}}
|
expectedClient := &APIClient{apiQuerier: &nomadAPIClient{}}
|
||||||
err := expectedClient.init(&TestURL, TestNamespace)
|
err := expectedClient.init(&TestURL, TestNamespace, TestNomadToken)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
_, err = NewExecutorAPI(&TestURL, TestNamespace)
|
_, err = NewExecutorAPI(&TestURL, TestNamespace, TestNomadToken)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user