diff --git a/cli/daemon.go b/cli/daemon.go index 7bfa5d0..d2b439a 100644 --- a/cli/daemon.go +++ b/cli/daemon.go @@ -10,7 +10,7 @@ func getDaemonCommand() *cobra.Command { Use: "daemon", Short: "Starts a daemon instance.", RunE: func(cmd *cobra.Command, args []string) error { - d := daemon.NewDaemon("", 8000) + d := daemon.NewDaemon("", 8000, nil) d.Start() return nil diff --git a/daemon/api.go b/daemon/api.go index 0f594d0..ec52f77 100644 --- a/daemon/api.go +++ b/daemon/api.go @@ -1,16 +1,17 @@ package daemon import ( + "context" "net/http" ) -func GetApiRoutes() map[string]http.HandlerFunc { - return map[string]http.HandlerFunc{ +func GetApiRoutes() map[string]HandlerFuncWithContext { + return map[string]HandlerFuncWithContext{ "/service": ServiceList, } } -func ServiceList(w http.ResponseWriter, r *http.Request) { +func ServiceList(w http.ResponseWriter, r *http.Request, c context.Context) { var returnPayload []byte var returnCode int diff --git a/daemon/api_test.go b/daemon/api_test.go index 62e54d4..034f1bd 100644 --- a/daemon/api_test.go +++ b/daemon/api_test.go @@ -1,6 +1,7 @@ package daemon import ( + "context" "net/http" "net/http/httptest" "testing" @@ -12,7 +13,7 @@ func TestServiceListUnsupportedMethods(t *testing.T) { req := httptest.NewRequest(method, "/service", nil) resp := httptest.NewRecorder() - ServiceList(resp, req) + ServiceList(resp, req, context.Background()) response := resp.Result() diff --git a/daemon/daemon.go b/daemon/daemon.go index 1c36579..a684439 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -1,17 +1,37 @@ package daemon import ( + "context" "fmt" "net/http" + service "spud/service" ) type Daemon struct { - Host string - Port int + Host string + Port int + Services service.ServiceClient + Routes map[string]http.HandlerFunc } -func NewDaemon(host string, port int) *Daemon { - return &Daemon{Host: host, Port: port} +type HandlerFuncWithContext = func(w http.ResponseWriter, r *http.Request, c context.Context) + +func handleFuncWithContext(h HandlerFuncWithContext, c context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + h(w, r, c) + } +} + +func NewDaemon(host string, port int, serviceClient service.ServiceClient) *Daemon { + d := &Daemon{Host: host, Port: port} + + if serviceClient == nil { + d.Services = &service.PodmanServiceClient{} + } else { + d.Services = serviceClient + } + + return d } func (d Daemon) GetListenAddress() string { @@ -19,8 +39,9 @@ func (d Daemon) GetListenAddress() string { } func (d Daemon) Start() { + daemonContext := context.WithValue(context.Background(), "client", d.Services) for route, handler := range GetApiRoutes() { - http.HandleFunc(route, handler) + http.HandleFunc(route, handleFuncWithContext(handler, daemonContext)) } http.ListenAndServe(d.GetListenAddress(), nil) diff --git a/daemon/daemon_test.go b/daemon/daemon_test.go new file mode 100644 index 0000000..9b97a39 --- /dev/null +++ b/daemon/daemon_test.go @@ -0,0 +1,31 @@ +package daemon + +import ( + "reflect" + service "spud/service" + service_definition "spud/service_definition" + "testing" +) + +type DummyClient struct{} + +func (c DummyClient) Create(d service_definition.ServiceDefinition) {} +func (c DummyClient) Stop(d string) {} + +func TestDaemonDefaultsToPodmanClient(t *testing.T) { + d := NewDaemon("host", 0, nil) + + clientType := reflect.TypeOf(d.Services).String() + if clientType != reflect.TypeOf(&service.PodmanServiceClient{}).String() { + t.Errorf("Expected podman client, got %s instead.", clientType) + } +} + +func TestDaemonUsesInjectedClientIfProvided(t *testing.T) { + d := NewDaemon("host", 0, DummyClient{}) + + clientType := reflect.TypeOf(d.Services).String() + if clientType != reflect.TypeOf(DummyClient{}).String() { + t.Errorf("Expected dummy client, got %s instead.", clientType) + } +} diff --git a/service/client.go b/service/client.go new file mode 100644 index 0000000..a8dcd38 --- /dev/null +++ b/service/client.go @@ -0,0 +1,10 @@ +package service + +import ( + service_definition "spud/service_definition" +) + +type ServiceClient interface { + Create(service_definition.ServiceDefinition) + Stop(string) +} diff --git a/service/service.go b/service/service.go index b616e3e..7ed7ef9 100644 --- a/service/service.go +++ b/service/service.go @@ -7,6 +7,16 @@ import ( service_definition "spud/service_definition" ) +type PodmanServiceClient struct{} + +func (c PodmanServiceClient) Create(definition service_definition.ServiceDefinition) { + CreateService(definition) +} + +func (c PodmanServiceClient) Stop(name string) { + StopService(name) +} + func CreateService(definition service_definition.ServiceDefinition) { var err error