From 2f96577057af6c254a7513cedbbd5ce240175305 Mon Sep 17 00:00:00 2001 From: deviantony Date: Thu, 8 Sep 2022 12:43:35 +0000 Subject: [PATCH 1/5] feat(sosivio): add the ability to query sosivio API --- http/handler/handler.go | 5 ++++ http/handler/sosivio/handler.go | 27 ++++++++++++++++++++++ http/handler/sosivio/namespaces.go | 37 ++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 http/handler/sosivio/handler.go create mode 100644 http/handler/sosivio/namespaces.go diff --git a/http/handler/handler.go b/http/handler/handler.go index ba07f44be..18bcbcf52 100644 --- a/http/handler/handler.go +++ b/http/handler/handler.go @@ -19,6 +19,7 @@ import ( "github.com/portainer/agent/http/handler/kubernetesproxy" "github.com/portainer/agent/http/handler/nomadproxy" "github.com/portainer/agent/http/handler/ping" + "github.com/portainer/agent/http/handler/sosivio" "github.com/portainer/agent/http/handler/websocket" "github.com/portainer/agent/http/proxy" "github.com/portainer/agent/http/security" @@ -40,6 +41,7 @@ type Handler struct { webSocketHandler *websocket.Handler hostHandler *host.Handler pingHandler *ping.Handler + sosivioHandler *sosivio.Handler containerPlatform agent.ContainerPlatform } @@ -78,6 +80,7 @@ func NewHandler(config *Config) *Handler { webSocketHandler: websocket.NewHandler(config.ClusterService, config.RuntimeConfiguration, notaryService, config.KubeClient), hostHandler: host.NewHandler(config.SystemService, agentProxy, notaryService), pingHandler: ping.NewHandler(), + sosivioHandler: sosivio.NewHandler(notaryService), containerPlatform: config.ContainerPlatform, } } @@ -119,6 +122,8 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, request *http.Request) { h.kubernetesProxyHandler.ServeHTTP(rw, request) case strings.HasPrefix(request.URL.Path, "/nomad"): h.nomadProxyHandler.ServeHTTP(rw, request) + case strings.HasPrefix(request.URL.Path, "/sosivio"): + h.sosivioHandler.ServeHTTP(rw, request) case strings.HasPrefix(request.URL.Path, "/"): h.dockerProxyHandler.ServeHTTP(rw, request) } diff --git a/http/handler/sosivio/handler.go b/http/handler/sosivio/handler.go new file mode 100644 index 000000000..5db144325 --- /dev/null +++ b/http/handler/sosivio/handler.go @@ -0,0 +1,27 @@ +package sosivio + +import ( + "net/http" + + "github.com/gorilla/mux" + "github.com/portainer/agent/http/security" + httperror "github.com/portainer/libhttp/error" +) + +// Handler is the HTTP handler used to handle Sosivio operations. +type Handler struct { + *mux.Router +} + +// NewHandler returns a pointer to an Handler +// It sets the associated handle functions for all the Sosivio related HTTP endpoints. +func NewHandler(notaryService *security.NotaryService) *Handler { + h := &Handler{ + Router: mux.NewRouter(), + } + + h.Handle("/sosivio/namespaces", + notaryService.DigitalSignatureVerification(httperror.LoggerHandler(h.namespaces))).Methods(http.MethodGet) + + return h +} diff --git a/http/handler/sosivio/namespaces.go b/http/handler/sosivio/namespaces.go new file mode 100644 index 000000000..8cf032101 --- /dev/null +++ b/http/handler/sosivio/namespaces.go @@ -0,0 +1,37 @@ +package sosivio + +import ( + "io/ioutil" + "net/http" + + httperror "github.com/portainer/libhttp/error" +) + +// TODO: REVIEW-POC-SOSIVIO +// Port to libhttp. +// Raw returns raw data. Returns a pointer to a +// HandlerError if encoding fails. +func Raw(rw http.ResponseWriter, data []byte) *httperror.HandlerError { + rw.Write(data) + return nil +} + +// GET request on /sosivio/namespaces +func (handler *Handler) namespaces(rw http.ResponseWriter, r *http.Request) *httperror.HandlerError { + + // TODO: REVIEW-POC-SOSIVIO + // Make use of a proper HTTP client here to manage timeouts + // Alternatively, a proxy can probably be used to handle ALL Sosivio related requests. + resp, err := http.Get("http://api-pod.portainer:8088/api/v1/namespaces") + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to query Sosivio API", err} + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to parse Sosivio API response", err} + } + + return Raw(rw, body) +} From 558d2453409a682efa090b79522407c439589dff Mon Sep 17 00:00:00 2001 From: deviantony Date: Thu, 8 Sep 2022 13:17:21 +0000 Subject: [PATCH 2/5] feat(sosivio): use service hostname --- http/handler/sosivio/namespaces.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http/handler/sosivio/namespaces.go b/http/handler/sosivio/namespaces.go index 8cf032101..4f939a586 100644 --- a/http/handler/sosivio/namespaces.go +++ b/http/handler/sosivio/namespaces.go @@ -22,7 +22,7 @@ func (handler *Handler) namespaces(rw http.ResponseWriter, r *http.Request) *htt // TODO: REVIEW-POC-SOSIVIO // Make use of a proper HTTP client here to manage timeouts // Alternatively, a proxy can probably be used to handle ALL Sosivio related requests. - resp, err := http.Get("http://api-pod.portainer:8088/api/v1/namespaces") + resp, err := http.Get("http://poc-api.portainer.svc.cluster.local:8088/api/v1/namespaces") if err != nil { return &httperror.HandlerError{http.StatusInternalServerError, "Unable to query Sosivio API", err} } From bcbfca8cd71a095859613c7d8d8145de8f29a115 Mon Sep 17 00:00:00 2001 From: deviantony Date: Thu, 15 Sep 2022 06:41:14 +0000 Subject: [PATCH 3/5] feat(sosivio): add the ability to query commandcenter --- http/handler/sosivio/commandcenter.go | 28 +++++++++++++++++++++++++++ http/handler/sosivio/handler.go | 12 +++++++++++- http/handler/sosivio/namespaces.go | 9 --------- 3 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 http/handler/sosivio/commandcenter.go diff --git a/http/handler/sosivio/commandcenter.go b/http/handler/sosivio/commandcenter.go new file mode 100644 index 000000000..22647b5bd --- /dev/null +++ b/http/handler/sosivio/commandcenter.go @@ -0,0 +1,28 @@ +package sosivio + +import ( + "io/ioutil" + "net/http" + + httperror "github.com/portainer/libhttp/error" +) + +// GET request on /sosivio/commandcenter +func (handler *Handler) commandCenter(rw http.ResponseWriter, r *http.Request) *httperror.HandlerError { + + // TODO: REVIEW-POC-SOSIVIO + // Make use of a proper HTTP client here to manage timeouts + // Alternatively, a proxy can probably be used to handle ALL Sosivio related requests. + resp, err := http.Get("http://poc-api.portainer.svc.cluster.local:8088/api/v1/commandcenter?" + r.URL.RawQuery) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to query Sosivio API", err} + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to parse Sosivio API response", err} + } + + return Raw(rw, body) +} diff --git a/http/handler/sosivio/handler.go b/http/handler/sosivio/handler.go index 5db144325..ad755cf81 100644 --- a/http/handler/sosivio/handler.go +++ b/http/handler/sosivio/handler.go @@ -22,6 +22,16 @@ func NewHandler(notaryService *security.NotaryService) *Handler { h.Handle("/sosivio/namespaces", notaryService.DigitalSignatureVerification(httperror.LoggerHandler(h.namespaces))).Methods(http.MethodGet) - + h.Handle("/sosivio/commandcenter", + notaryService.DigitalSignatureVerification(httperror.LoggerHandler(h.commandCenter))).Methods(http.MethodGet) return h } + +// TODO: REVIEW-POC-SOSIVIO +// Port to libhttp. +// Raw returns raw data. Returns a pointer to a +// HandlerError if encoding fails. +func Raw(rw http.ResponseWriter, data []byte) *httperror.HandlerError { + rw.Write(data) + return nil +} diff --git a/http/handler/sosivio/namespaces.go b/http/handler/sosivio/namespaces.go index 4f939a586..caa0d19d3 100644 --- a/http/handler/sosivio/namespaces.go +++ b/http/handler/sosivio/namespaces.go @@ -7,15 +7,6 @@ import ( httperror "github.com/portainer/libhttp/error" ) -// TODO: REVIEW-POC-SOSIVIO -// Port to libhttp. -// Raw returns raw data. Returns a pointer to a -// HandlerError if encoding fails. -func Raw(rw http.ResponseWriter, data []byte) *httperror.HandlerError { - rw.Write(data) - return nil -} - // GET request on /sosivio/namespaces func (handler *Handler) namespaces(rw http.ResponseWriter, r *http.Request) *httperror.HandlerError { From 0437cbced99e49a388f551de0045664ee5cb4ff2 Mon Sep 17 00:00:00 2001 From: deviantony Date: Fri, 23 Sep 2022 08:23:44 +0000 Subject: [PATCH 4/5] feat(sosivio): add the ability to query pod and node metrics --- http/handler/sosivio/handler.go | 4 ++++ http/handler/sosivio/nodes.go | 28 ++++++++++++++++++++++++++++ http/handler/sosivio/pods.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 http/handler/sosivio/nodes.go create mode 100644 http/handler/sosivio/pods.go diff --git a/http/handler/sosivio/handler.go b/http/handler/sosivio/handler.go index ad755cf81..ec43bf57c 100644 --- a/http/handler/sosivio/handler.go +++ b/http/handler/sosivio/handler.go @@ -22,6 +22,10 @@ func NewHandler(notaryService *security.NotaryService) *Handler { h.Handle("/sosivio/namespaces", notaryService.DigitalSignatureVerification(httperror.LoggerHandler(h.namespaces))).Methods(http.MethodGet) + h.Handle("/sosivio/pods", + notaryService.DigitalSignatureVerification(httperror.LoggerHandler(h.pods))).Methods(http.MethodGet) + h.Handle("/sosivio/nodes", + notaryService.DigitalSignatureVerification(httperror.LoggerHandler(h.nodes))).Methods(http.MethodGet) h.Handle("/sosivio/commandcenter", notaryService.DigitalSignatureVerification(httperror.LoggerHandler(h.commandCenter))).Methods(http.MethodGet) return h diff --git a/http/handler/sosivio/nodes.go b/http/handler/sosivio/nodes.go new file mode 100644 index 000000000..d46fd562c --- /dev/null +++ b/http/handler/sosivio/nodes.go @@ -0,0 +1,28 @@ +package sosivio + +import ( + "io/ioutil" + "net/http" + + httperror "github.com/portainer/libhttp/error" +) + +// GET request on /sosivio/nodes +func (handler *Handler) nodes(rw http.ResponseWriter, r *http.Request) *httperror.HandlerError { + + // TODO: REVIEW-POC-SOSIVIO + // Make use of a proper HTTP client here to manage timeouts + // Alternatively, a proxy can probably be used to handle ALL Sosivio related requests. + resp, err := http.Get("http://poc-api.portainer.svc.cluster.local:8088/api/v1/node?" + r.URL.RawQuery) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to query Sosivio API", err} + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to parse Sosivio API response", err} + } + + return Raw(rw, body) +} diff --git a/http/handler/sosivio/pods.go b/http/handler/sosivio/pods.go new file mode 100644 index 000000000..7b861dfda --- /dev/null +++ b/http/handler/sosivio/pods.go @@ -0,0 +1,28 @@ +package sosivio + +import ( + "io/ioutil" + "net/http" + + httperror "github.com/portainer/libhttp/error" +) + +// GET request on /sosivio/pods +func (handler *Handler) pods(rw http.ResponseWriter, r *http.Request) *httperror.HandlerError { + + // TODO: REVIEW-POC-SOSIVIO + // Make use of a proper HTTP client here to manage timeouts + // Alternatively, a proxy can probably be used to handle ALL Sosivio related requests. + resp, err := http.Get("http://poc-api.portainer.svc.cluster.local:8088/api/v1/pod?" + r.URL.RawQuery) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to query Sosivio API", err} + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to parse Sosivio API response", err} + } + + return Raw(rw, body) +} From cc1c624e6520ac208d92c9c7580e312ceb5cae62 Mon Sep 17 00:00:00 2001 From: deviantony Date: Mon, 26 Sep 2022 10:09:33 +0000 Subject: [PATCH 5/5] feat(sosivio): support query params for namespaces request --- http/handler/sosivio/namespaces.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http/handler/sosivio/namespaces.go b/http/handler/sosivio/namespaces.go index caa0d19d3..55178667c 100644 --- a/http/handler/sosivio/namespaces.go +++ b/http/handler/sosivio/namespaces.go @@ -13,7 +13,7 @@ func (handler *Handler) namespaces(rw http.ResponseWriter, r *http.Request) *htt // TODO: REVIEW-POC-SOSIVIO // Make use of a proper HTTP client here to manage timeouts // Alternatively, a proxy can probably be used to handle ALL Sosivio related requests. - resp, err := http.Get("http://poc-api.portainer.svc.cluster.local:8088/api/v1/namespaces") + resp, err := http.Get("http://poc-api.portainer.svc.cluster.local:8088/api/v1/namespaces?" + r.URL.RawQuery) if err != nil { return &httperror.HandlerError{http.StatusInternalServerError, "Unable to query Sosivio API", err} }