feat: add service start/stop via daemon api
This commit is contained in:
parent
01df6c4dd5
commit
d51031a875
2 changed files with 116 additions and 14 deletions
|
@ -2,28 +2,58 @@ package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
service "spud/service"
|
||||||
|
service_definition "spud/service_definition"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetApiRoutes() map[string]HandlerFuncWithContext {
|
func GetApiRoutes() map[string]HandlerFuncWithContext {
|
||||||
return map[string]HandlerFuncWithContext{
|
return map[string]HandlerFuncWithContext{
|
||||||
"/service": ServiceList,
|
"/service/": ServiceList,
|
||||||
|
"/service/{serviceName}/": ServiceDetails,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ServiceListPayload struct {
|
||||||
|
Definition service_definition.ServiceDefinition `json:"definition"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleServiceListPost(w http.ResponseWriter, r *http.Request, c context.Context) {
|
||||||
|
client := c.Value("client").(service.ServiceClient)
|
||||||
|
var p ServiceListPayload
|
||||||
|
json.NewDecoder(r.Body).Decode(&p)
|
||||||
|
client.Create(p.Definition)
|
||||||
|
w.WriteHeader(201)
|
||||||
|
json.NewEncoder(w).Encode(p.Definition)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleServiceDetailDelete(w http.ResponseWriter, r *http.Request, c context.Context) {
|
||||||
|
client := c.Value("client").(service.ServiceClient)
|
||||||
|
serviceName := r.PathValue("serviceName")
|
||||||
|
client.Stop(serviceName)
|
||||||
|
|
||||||
|
w.WriteHeader(204)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleNotImplemented(w http.ResponseWriter) {
|
||||||
|
w.WriteHeader(501)
|
||||||
|
}
|
||||||
|
|
||||||
func ServiceList(w http.ResponseWriter, r *http.Request, c context.Context) {
|
func ServiceList(w http.ResponseWriter, r *http.Request, c context.Context) {
|
||||||
var returnPayload []byte
|
|
||||||
var returnCode int
|
|
||||||
|
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case "POST":
|
case http.MethodPost:
|
||||||
returnPayload = []byte("Create service: Not implemented")
|
handleServiceListPost(w, r, c)
|
||||||
returnCode = 501
|
|
||||||
default:
|
default:
|
||||||
returnPayload = []byte("Not implemented")
|
handleNotImplemented(w)
|
||||||
returnCode = 501
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ServiceDetails(w http.ResponseWriter, r *http.Request, c context.Context) {
|
||||||
|
switch r.Method {
|
||||||
|
case http.MethodDelete:
|
||||||
|
handleServiceDetailDelete(w, r, c)
|
||||||
|
default:
|
||||||
|
handleNotImplemented(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(returnCode)
|
|
||||||
w.Write(returnPayload)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,48 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
service_definition "spud/service_definition"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type MockClient struct {
|
||||||
|
calls struct {
|
||||||
|
Create []service_definition.ServiceDefinition
|
||||||
|
Stop []string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MockClient) Create(s service_definition.ServiceDefinition) {
|
||||||
|
c.calls.Create = append(c.calls.Create, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MockClient) Stop(n string) {
|
||||||
|
c.calls.Stop = append(c.calls.Stop, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServiceListPostCreatesService(t *testing.T) {
|
||||||
|
mockClient := &MockClient{}
|
||||||
|
daemonContext := context.WithValue(context.Background(), "client", mockClient)
|
||||||
|
req := httptest.NewRequest(http.MethodPost, "/service/", nil)
|
||||||
|
resp := httptest.NewRecorder()
|
||||||
|
|
||||||
|
ServiceList(resp, req, daemonContext)
|
||||||
|
|
||||||
|
response := resp.Result()
|
||||||
|
|
||||||
|
if response.StatusCode != 201 {
|
||||||
|
t.Errorf("Expected status 201, got %d", response.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(mockClient.calls.Create) != 1 {
|
||||||
|
t.Error("Expected a call to Create")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestServiceListUnsupportedMethods(t *testing.T) {
|
func TestServiceListUnsupportedMethods(t *testing.T) {
|
||||||
for _, method := range []string{http.MethodGet, http.MethodPut, http.MethodHead} {
|
for _, method := range []string{http.MethodGet, http.MethodPut, http.MethodHead, http.MethodDelete} {
|
||||||
t.Run(method, func(t *testing.T) {
|
t.Run(method, func(t *testing.T) {
|
||||||
req := httptest.NewRequest(method, "/service", nil)
|
req := httptest.NewRequest(method, "/service/", nil)
|
||||||
resp := httptest.NewRecorder()
|
resp := httptest.NewRecorder()
|
||||||
|
|
||||||
ServiceList(resp, req, context.Background())
|
ServiceList(resp, req, context.Background())
|
||||||
|
@ -24,3 +59,40 @@ func TestServiceListUnsupportedMethods(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServiceDetailsDeleteStopsService(t *testing.T) {
|
||||||
|
mockClient := &MockClient{}
|
||||||
|
daemonContext := context.WithValue(context.Background(), "client", mockClient)
|
||||||
|
req := httptest.NewRequest(http.MethodDelete, "/service/service-name/", nil)
|
||||||
|
resp := httptest.NewRecorder()
|
||||||
|
|
||||||
|
ServiceDetails(resp, req, daemonContext)
|
||||||
|
|
||||||
|
response := resp.Result()
|
||||||
|
|
||||||
|
if response.StatusCode != 204 {
|
||||||
|
t.Errorf("Expected status 204, got %d", response.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(mockClient.calls.Stop) != 1 {
|
||||||
|
t.Error("Expected a call to Stop")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServiceDetailUnsupportedMethods(t *testing.T) {
|
||||||
|
for _, method := range []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodHead} {
|
||||||
|
t.Run(method, func(t *testing.T) {
|
||||||
|
req := httptest.NewRequest(method, "/service/service-name/", nil)
|
||||||
|
resp := httptest.NewRecorder()
|
||||||
|
|
||||||
|
ServiceDetails(resp, req, context.Background())
|
||||||
|
|
||||||
|
response := resp.Result()
|
||||||
|
|
||||||
|
if response.StatusCode != 501 {
|
||||||
|
t.Errorf("Expected status 501, got %d.", response.StatusCode)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue