diff --git a/api/http/handler/handler.go b/api/http/handler/handler.go index 9be2024b3..746b629a7 100644 --- a/api/http/handler/handler.go +++ b/api/http/handler/handler.go @@ -99,7 +99,7 @@ type Handler struct { // @securitydefinitions.apikey ApiKeyAuth // @in header -// @name x-api-key +// @name X-API-KEY // @securitydefinitions.apikey jwt // @in header diff --git a/api/http/handler/kubernetes/config.go b/api/http/handler/kubernetes/config.go index 208b6da73..e0b596054 100644 --- a/api/http/handler/kubernetes/config.go +++ b/api/http/handler/kubernetes/config.go @@ -16,8 +16,8 @@ import ( ) // @id GetKubernetesConfig -// @summary Generates kubeconfig file enabling client communication with k8s api server -// @description Generates kubeconfig file enabling client communication with k8s api server +// @summary Generate a kubeconfig file enabling client communication with k8s api server +// @description Generate a kubeconfig file enabling client communication with k8s api server // @description **Access policy**: authenticated // @tags kubernetes // @security ApiKeyAuth diff --git a/api/http/handler/kubernetes/configmaps_and_secrets.go b/api/http/handler/kubernetes/configmaps_and_secrets.go index d1c7af22f..11f9a5605 100644 --- a/api/http/handler/kubernetes/configmaps_and_secrets.go +++ b/api/http/handler/kubernetes/configmaps_and_secrets.go @@ -9,7 +9,22 @@ import ( "github.com/portainer/libhttp/response" ) -func (handler *Handler) getKubernetesConfigMaps(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { +// @id getKubernetesConfigMapsAndSecrets +// @summary Get ConfigMaps and Secrets +// @description Get all ConfigMaps and Secrets for a given namespace +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace name" +// @success 200 {array} kubernetes.K8sConfigMapOrSecret "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace}/configuration [get] +func (handler *Handler) getKubernetesConfigMapsAndSecrets(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { return httperror.BadRequest( diff --git a/api/http/handler/kubernetes/handler.go b/api/http/handler/kubernetes/handler.go index 19927fbc1..c6bda07d3 100644 --- a/api/http/handler/kubernetes/handler.go +++ b/api/http/handler/kubernetes/handler.go @@ -61,7 +61,7 @@ func NewHandler(bouncer *security.RequestBouncer, authorizationService *authoriz endpointRouter.Path("/namespaces").Handler(httperror.LoggerHandler(h.createKubernetesNamespace)).Methods(http.MethodPost) endpointRouter.Path("/namespaces").Handler(httperror.LoggerHandler(h.updateKubernetesNamespace)).Methods(http.MethodPut) endpointRouter.Path("/namespaces").Handler(httperror.LoggerHandler(h.getKubernetesNamespaces)).Methods(http.MethodGet) - endpointRouter.Path("/namespace/{namespace}").Handler(httperror.LoggerHandler(h.deleteKubernetesNamespaces)).Methods(http.MethodDelete) + endpointRouter.Path("/namespace/{namespace}").Handler(httperror.LoggerHandler(h.deleteKubernetesNamespace)).Methods(http.MethodDelete) endpointRouter.Path("/namespaces/{namespace}").Handler(httperror.LoggerHandler(h.getKubernetesNamespace)).Methods(http.MethodGet) // namespaces @@ -71,7 +71,7 @@ func NewHandler(bouncer *security.RequestBouncer, authorizationService *authoriz namespaceRouter.Handle("/system", bouncer.RestrictedAccess(httperror.LoggerHandler(h.namespacesToggleSystem))).Methods(http.MethodPut) namespaceRouter.Handle("/ingresscontrollers", httperror.LoggerHandler(h.getKubernetesIngressControllersByNamespace)).Methods(http.MethodGet) namespaceRouter.Handle("/ingresscontrollers", httperror.LoggerHandler(h.updateKubernetesIngressControllersByNamespace)).Methods(http.MethodPut) - namespaceRouter.Handle("/configmaps", httperror.LoggerHandler(h.getKubernetesConfigMaps)).Methods(http.MethodGet) + namespaceRouter.Handle("/configuration", httperror.LoggerHandler(h.getKubernetesConfigMapsAndSecrets)).Methods(http.MethodGet) namespaceRouter.Handle("/ingresses", httperror.LoggerHandler(h.createKubernetesIngress)).Methods(http.MethodPost) namespaceRouter.Handle("/ingresses", httperror.LoggerHandler(h.updateKubernetesIngress)).Methods(http.MethodPut) namespaceRouter.Handle("/ingresses", httperror.LoggerHandler(h.getKubernetesIngresses)).Methods(http.MethodGet) diff --git a/api/http/handler/kubernetes/ingresses.go b/api/http/handler/kubernetes/ingresses.go index 1e03ed7ee..f81189d52 100644 --- a/api/http/handler/kubernetes/ingresses.go +++ b/api/http/handler/kubernetes/ingresses.go @@ -12,6 +12,21 @@ import ( "github.com/portainer/portainer/api/http/security" ) +// @id getKubernetesIngressControllers +// @summary Get a list of ingress controllers +// @description Get a list of ingress controllers for the given environment +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param allowedOnly query boolean false "Only return allowed ingress controllers" +// @success 200 {object} models.K8sIngressControllers "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/ingresscontrollers [get] func (handler *Handler) getKubernetesIngressControllers(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { @@ -117,6 +132,21 @@ func (handler *Handler) getKubernetesIngressControllers(w http.ResponseWriter, r return response.JSON(w, controllers) } +// @id getKubernetesIngressControllersByNamespace +// @summary Get a list ingress controllers by namespace +// @description Get a list of ingress controllers for the given environment in the provided namespace +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace" +// @success 200 {object} models.K8sIngressControllers "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace}/ingresscontrollers [get] func (handler *Handler) getKubernetesIngressControllersByNamespace(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { @@ -231,6 +261,21 @@ func (handler *Handler) getKubernetesIngressControllersByNamespace(w http.Respon return response.JSON(w, controllers) } +// @id updateKubernetesIngressControllers +// @summary Update (block/unblock) ingress controllers +// @description Update (block/unblock) ingress controllers +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param body body []models.K8sIngressControllers true "Ingress controllers" +// @success 200 {string} string "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/ingresscontrollers [put] func (handler *Handler) updateKubernetesIngressControllers(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") @@ -334,6 +379,22 @@ func (handler *Handler) updateKubernetesIngressControllers(w http.ResponseWriter return response.Empty(w) } +// @id updateKubernetesIngressControllersByNamespace +// @summary Update (block/unblock) ingress controllers by namespace +// @description Update (block/unblock) ingress controllers by namespace for the provided environment +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace name" +// @param body body []models.K8sIngressControllers true "Ingress controllers" +// @success 200 {string} string "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace}/ingresscontrollers [put] func (handler *Handler) updateKubernetesIngressControllersByNamespace(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { @@ -451,6 +512,22 @@ PayloadLoop: return response.Empty(w) } +// @id getKubernetesIngresses +// @summary Get kubernetes ingresses by namespace +// @description Get kubernetes ingresses by namespace for the provided environment +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace name" +// @param body body []models.K8sIngressInfo true "Ingress details" +// @success 200 {string} string "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace}/ingresses [get] func (handler *Handler) getKubernetesIngresses(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { namespace, err := request.RetrieveRouteVariableValue(r, "namespace") if err != nil { @@ -489,6 +566,22 @@ func (handler *Handler) getKubernetesIngresses(w http.ResponseWriter, r *http.Re return response.JSON(w, ingresses) } +// @id createKubernetesIngress +// @summary Create a kubernetes ingress by namespace +// @description Create a kubernetes ingress by namespace for the provided environment +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace name" +// @param body body models.K8sIngressInfo true "Ingress details" +// @success 200 {string} string "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace}/ingresses [post] func (handler *Handler) createKubernetesIngress(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { namespace, err := request.RetrieveRouteVariableValue(r, "namespace") if err != nil { @@ -541,6 +634,21 @@ func (handler *Handler) createKubernetesIngress(w http.ResponseWriter, r *http.R return response.Empty(w) } +// @id deleteKubernetesIngresses +// @summary Delete kubernetes ingresses +// @description Delete kubernetes ingresses for the provided environment +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param body body models.K8sIngressDeleteRequests true "Ingress details" +// @success 200 {string} string "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/ingresses/delete [post] func (handler *Handler) deleteKubernetesIngresses(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { @@ -576,6 +684,22 @@ func (handler *Handler) deleteKubernetesIngresses(w http.ResponseWriter, r *http return response.Empty(w) } +// @id updateKubernetesIngress +// @summary Update kubernetes ingress rule +// @description Update kubernetes ingress rule for the provided environment +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace name" +// @param body body models.K8sIngressInfo true "Ingress details" +// @success 200 {string} string "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace}/ingresses [put] func (handler *Handler) updateKubernetesIngress(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { namespace, err := request.RetrieveRouteVariableValue(r, "namespace") if err != nil { diff --git a/api/http/handler/kubernetes/namespaces.go b/api/http/handler/kubernetes/namespaces.go index 5f049ad5e..25e3a628a 100644 --- a/api/http/handler/kubernetes/namespaces.go +++ b/api/http/handler/kubernetes/namespaces.go @@ -10,6 +10,20 @@ import ( models "github.com/portainer/portainer/api/http/models/kubernetes" ) +// @id getKubernetesNamespaces +// @summary Get a list of kubernetes namespaces +// @description Get a list of all kubernetes namespaces in the cluster +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @success 200 {object} map[string]portainer.K8sNamespaceInfo "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces [get] func (handler *Handler) getKubernetesNamespaces(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { @@ -40,6 +54,21 @@ func (handler *Handler) getKubernetesNamespaces(w http.ResponseWriter, r *http.R return response.JSON(w, namespaces) } +// @id getKubernetesNamespace +// @summary Get kubernetes namespace details +// @description Get kubernetes namespace details for the provided namespace within the given environment +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace" +// @success 200 {object} portainer.K8sNamespaceInfo "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace} [get] func (handler *Handler) getKubernetesNamespace(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { @@ -77,6 +106,22 @@ func (handler *Handler) getKubernetesNamespace(w http.ResponseWriter, r *http.Re return response.JSON(w, namespace) } +// @id createKubernetesNamespace +// @summary Create a kubernetes namespace +// @description Create a kubernetes namespace within the given environment +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace" +// @param body body models.K8sNamespaceDetails true "Namespace configuration details" +// @success 200 {string} string "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace} [post] func (handler *Handler) createKubernetesNamespace(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { @@ -115,7 +160,22 @@ func (handler *Handler) createKubernetesNamespace(w http.ResponseWriter, r *http return nil } -func (handler *Handler) deleteKubernetesNamespaces(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { +// @id deleteKubernetesNamespace +// @summary Delete kubernetes namespace +// @description Delete a kubernetes namespace within the given environment +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace" +// @success 200 {string} string "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace} [delete] +func (handler *Handler) deleteKubernetesNamespace(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { return httperror.BadRequest( @@ -153,6 +213,22 @@ func (handler *Handler) deleteKubernetesNamespaces(w http.ResponseWriter, r *htt return nil } +// @id updateKubernetesNamespace +// @summary Updates a kubernetes namespace +// @description Update a kubernetes namespace within the given environment +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace" +// @param body body models.K8sNamespaceDetails true "Namespace details" +// @success 200 {string} string "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace} [put] func (handler *Handler) updateKubernetesNamespace(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { diff --git a/api/http/handler/kubernetes/services.go b/api/http/handler/kubernetes/services.go index 9647143f0..76fc5906f 100644 --- a/api/http/handler/kubernetes/services.go +++ b/api/http/handler/kubernetes/services.go @@ -10,6 +10,22 @@ import ( models "github.com/portainer/portainer/api/http/models/kubernetes" ) +// @id getKubernetesServices +// @summary Get a list of kubernetes services for a given namespace +// @description Get a list of kubernetes services for a given namespace +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace name" +// @param lookupapplications query boolean false "Lookup applications associated with each service" +// @success 200 {array} models.K8sServiceInfo "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace}/services [get] func (handler *Handler) getKubernetesServices(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { namespace, err := request.RetrieveRouteVariableValue(r, "namespace") if err != nil { @@ -56,6 +72,22 @@ func (handler *Handler) getKubernetesServices(w http.ResponseWriter, r *http.Req return response.JSON(w, services) } +// @id createKubernetesService +// @summary Create a kubernetes service +// @description Create a kubernetes service within a given namespace +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace name" +// @param body body models.K8sServiceInfo true "Service definition" +// @success 200 "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace}/services [post] func (handler *Handler) createKubernetesService(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { namespace, err := request.RetrieveRouteVariableValue(r, "namespace") if err != nil { @@ -102,6 +134,21 @@ func (handler *Handler) createKubernetesService(w http.ResponseWriter, r *http.R return nil } +// @id deleteKubernetesServices +// @summary Delete kubernetes services +// @description Delete the provided list of kubernetes services +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param body body models.K8sServiceDeleteRequests true "A map where the key is the namespace and the value is an array of services to delete" +// @success 200 "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/services/delete [post] func (handler *Handler) deleteKubernetesServices(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { @@ -140,6 +187,22 @@ func (handler *Handler) deleteKubernetesServices(w http.ResponseWriter, r *http. return nil } +// @id updateKubernetesService +// @summary Update a kubernetes service +// @description Update a kubernetes service within a given namespace +// @description **Access policy**: authenticated +// @tags kubernetes +// @security ApiKeyAuth +// @security jwt +// @accept json +// @produce json +// @param id path int true "Environment (Endpoint) identifier" +// @param namespace path string true "Namespace name" +// @param body body models.K8sServiceInfo true "Service definition" +// @success 200 "Success" +// @failure 400 "Invalid request" +// @failure 500 "Server error" +// @router /kubernetes/{id}/namespaces/{namespace}/services [put] func (handler *Handler) updateKubernetesService(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { namespace, err := request.RetrieveRouteVariableValue(r, "namespace") if err != nil { diff --git a/app/react/kubernetes/configs/service.ts b/app/react/kubernetes/configs/service.ts index 6e48ec6db..e9520c92e 100644 --- a/app/react/kubernetes/configs/service.ts +++ b/app/react/kubernetes/configs/service.ts @@ -10,7 +10,7 @@ export async function getConfigurations( ) { try { const { data: configmaps } = await axios.get( - `kubernetes/${environmentId}/namespaces/${namespace}/configmaps` + `kubernetes/${environmentId}/namespaces/${namespace}/configuration` ); return configmaps; } catch (e) {