mirror of https://github.com/portainer/portainer
748 lines
22 KiB
Go
748 lines
22 KiB
Go
package kubernetes
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
portainer "github.com/portainer/portainer/api"
|
|
models "github.com/portainer/portainer/api/http/models/kubernetes"
|
|
"github.com/portainer/portainer/api/http/security"
|
|
httperror "github.com/portainer/portainer/pkg/libhttp/error"
|
|
"github.com/portainer/portainer/pkg/libhttp/request"
|
|
"github.com/portainer/portainer/pkg/libhttp/response"
|
|
)
|
|
|
|
// @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 {
|
|
return httperror.BadRequest(
|
|
"Invalid environment identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
|
if handler.DataStore.IsErrObjectNotFound(err) {
|
|
return httperror.NotFound(
|
|
"Unable to find an environment with the specified identifier inside the database",
|
|
err,
|
|
)
|
|
} else if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to find an environment with the specified identifier inside the database",
|
|
err,
|
|
)
|
|
}
|
|
|
|
allowedOnly, err := request.RetrieveBooleanQueryParameter(r, "allowedOnly", true)
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid allowedOnly boolean query parameter",
|
|
err,
|
|
)
|
|
}
|
|
|
|
cli, err := handler.KubernetesClientFactory.GetKubeClient(endpoint)
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to create Kubernetes client",
|
|
err,
|
|
)
|
|
}
|
|
|
|
controllers, err := cli.GetIngressControllers()
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Failed to fetch ingressclasses",
|
|
err,
|
|
)
|
|
}
|
|
|
|
// Add none controller if "AllowNone" is set for endpoint.
|
|
if endpoint.Kubernetes.Configuration.AllowNoneIngressClass {
|
|
controllers = append(controllers, models.K8sIngressController{
|
|
Name: "none",
|
|
ClassName: "none",
|
|
Type: "custom",
|
|
})
|
|
}
|
|
existingClasses := endpoint.Kubernetes.Configuration.IngressClasses
|
|
var updatedClasses []portainer.KubernetesIngressClassConfig
|
|
for i := range controllers {
|
|
controllers[i].Availability = true
|
|
if controllers[i].ClassName != "none" {
|
|
controllers[i].New = true
|
|
}
|
|
|
|
var updatedClass portainer.KubernetesIngressClassConfig
|
|
updatedClass.Name = controllers[i].ClassName
|
|
updatedClass.Type = controllers[i].Type
|
|
|
|
// Check if the controller is already known.
|
|
for _, existingClass := range existingClasses {
|
|
if controllers[i].ClassName != existingClass.Name {
|
|
continue
|
|
}
|
|
controllers[i].New = false
|
|
controllers[i].Availability = !existingClass.GloballyBlocked
|
|
updatedClass.GloballyBlocked = existingClass.GloballyBlocked
|
|
updatedClass.BlockedNamespaces = existingClass.BlockedNamespaces
|
|
}
|
|
updatedClasses = append(updatedClasses, updatedClass)
|
|
}
|
|
|
|
endpoint.Kubernetes.Configuration.IngressClasses = updatedClasses
|
|
err = handler.DataStore.Endpoint().UpdateEndpoint(
|
|
portainer.EndpointID(endpointID),
|
|
endpoint,
|
|
)
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to store found IngressClasses inside the database",
|
|
err,
|
|
)
|
|
}
|
|
|
|
// If the allowedOnly query parameter was set. We need to prune out
|
|
// disallowed controllers from the response.
|
|
if allowedOnly {
|
|
var allowedControllers models.K8sIngressControllers
|
|
for _, controller := range controllers {
|
|
if controller.Availability {
|
|
allowedControllers = append(allowedControllers, controller)
|
|
}
|
|
}
|
|
controllers = allowedControllers
|
|
}
|
|
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 {
|
|
return httperror.BadRequest(
|
|
"Invalid environment identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
|
if handler.DataStore.IsErrObjectNotFound(err) {
|
|
return httperror.NotFound(
|
|
"Unable to find an environment with the specified identifier inside the database",
|
|
err,
|
|
)
|
|
} else if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to find an environment with the specified identifier inside the database",
|
|
err,
|
|
)
|
|
}
|
|
|
|
namespace, err := request.RetrieveRouteVariableValue(r, "namespace")
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid namespace identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
cli, ok := handler.KubernetesClientFactory.GetProxyKubeClient(
|
|
strconv.Itoa(endpointID), r.Header.Get("Authorization"),
|
|
)
|
|
if !ok {
|
|
return httperror.InternalServerError(
|
|
"Failed to lookup KubeClient",
|
|
nil,
|
|
)
|
|
}
|
|
|
|
currentControllers, err := cli.GetIngressControllers()
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Failed to fetch ingressclasses",
|
|
err,
|
|
)
|
|
}
|
|
// Add none controller if "AllowNone" is set for endpoint.
|
|
if endpoint.Kubernetes.Configuration.AllowNoneIngressClass {
|
|
currentControllers = append(currentControllers, models.K8sIngressController{
|
|
Name: "none",
|
|
ClassName: "none",
|
|
Type: "custom",
|
|
})
|
|
}
|
|
kubernetesConfig := endpoint.Kubernetes.Configuration
|
|
existingClasses := kubernetesConfig.IngressClasses
|
|
ingressAvailabilityPerNamespace := kubernetesConfig.IngressAvailabilityPerNamespace
|
|
var updatedClasses []portainer.KubernetesIngressClassConfig
|
|
var controllers models.K8sIngressControllers
|
|
for i := range currentControllers {
|
|
var globallyblocked bool
|
|
currentControllers[i].Availability = true
|
|
if currentControllers[i].ClassName != "none" {
|
|
currentControllers[i].New = true
|
|
}
|
|
|
|
var updatedClass portainer.KubernetesIngressClassConfig
|
|
updatedClass.Name = currentControllers[i].ClassName
|
|
updatedClass.Type = currentControllers[i].Type
|
|
|
|
// Check if the controller is blocked globally or in the current
|
|
// namespace.
|
|
for _, existingClass := range existingClasses {
|
|
if currentControllers[i].ClassName != existingClass.Name {
|
|
continue
|
|
}
|
|
currentControllers[i].New = false
|
|
updatedClass.GloballyBlocked = existingClass.GloballyBlocked
|
|
updatedClass.BlockedNamespaces = existingClass.BlockedNamespaces
|
|
|
|
globallyblocked = existingClass.GloballyBlocked
|
|
|
|
// Check if the current namespace is blocked if ingressAvailabilityPerNamespace is set to true
|
|
if ingressAvailabilityPerNamespace {
|
|
for _, ns := range existingClass.BlockedNamespaces {
|
|
if namespace == ns {
|
|
currentControllers[i].Availability = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if !globallyblocked {
|
|
controllers = append(controllers, currentControllers[i])
|
|
}
|
|
updatedClasses = append(updatedClasses, updatedClass)
|
|
}
|
|
|
|
// Update the database to match the list of found controllers.
|
|
// This includes pruning out controllers which no longer exist.
|
|
endpoint.Kubernetes.Configuration.IngressClasses = updatedClasses
|
|
err = handler.DataStore.Endpoint().UpdateEndpoint(
|
|
portainer.EndpointID(endpointID),
|
|
endpoint,
|
|
)
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to store found IngressClasses inside the database",
|
|
err,
|
|
)
|
|
}
|
|
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")
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid environment identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
|
if handler.DataStore.IsErrObjectNotFound(err) {
|
|
return httperror.NotFound(
|
|
"Unable to find an environment with the specified identifier inside the database",
|
|
err,
|
|
)
|
|
} else if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to find an environment with the specified identifier inside the database",
|
|
err,
|
|
)
|
|
}
|
|
|
|
var payload models.K8sIngressControllers
|
|
err = request.DecodeAndValidateJSONPayload(r, &payload)
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid request payload",
|
|
err,
|
|
)
|
|
}
|
|
|
|
cli, err := handler.KubernetesClientFactory.GetKubeClient(endpoint)
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to create Kubernetes client",
|
|
err,
|
|
)
|
|
}
|
|
|
|
existingClasses := endpoint.Kubernetes.Configuration.IngressClasses
|
|
controllers, err := cli.GetIngressControllers()
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to get ingress controllers",
|
|
err,
|
|
)
|
|
}
|
|
|
|
// Add none controller if "AllowNone" is set for endpoint.
|
|
if endpoint.Kubernetes.Configuration.AllowNoneIngressClass {
|
|
controllers = append(controllers, models.K8sIngressController{
|
|
Name: "none",
|
|
ClassName: "none",
|
|
Type: "custom",
|
|
})
|
|
}
|
|
|
|
var updatedClasses []portainer.KubernetesIngressClassConfig
|
|
for i := range controllers {
|
|
controllers[i].Availability = true
|
|
controllers[i].New = true
|
|
|
|
var updatedClass portainer.KubernetesIngressClassConfig
|
|
updatedClass.Name = controllers[i].ClassName
|
|
updatedClass.Type = controllers[i].Type
|
|
|
|
// Check if the controller is already known.
|
|
for _, existingClass := range existingClasses {
|
|
if controllers[i].ClassName != existingClass.Name {
|
|
continue
|
|
}
|
|
controllers[i].New = false
|
|
controllers[i].Availability = !existingClass.GloballyBlocked
|
|
updatedClass.GloballyBlocked = existingClass.GloballyBlocked
|
|
updatedClass.BlockedNamespaces = existingClass.BlockedNamespaces
|
|
}
|
|
updatedClasses = append(updatedClasses, updatedClass)
|
|
}
|
|
|
|
for _, p := range payload {
|
|
for i := range controllers {
|
|
// Now set new payload data
|
|
if updatedClasses[i].Name == p.ClassName {
|
|
updatedClasses[i].GloballyBlocked = !p.Availability
|
|
}
|
|
}
|
|
}
|
|
|
|
endpoint.Kubernetes.Configuration.IngressClasses = updatedClasses
|
|
err = handler.DataStore.Endpoint().UpdateEndpoint(
|
|
portainer.EndpointID(endpointID),
|
|
endpoint,
|
|
)
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to update the BlockedIngressClasses inside the database",
|
|
err,
|
|
)
|
|
}
|
|
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 {
|
|
return httperror.BadRequest(
|
|
"Invalid environment identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
|
if handler.DataStore.IsErrObjectNotFound(err) {
|
|
return httperror.NotFound(
|
|
"Unable to find an environment with the specified identifier inside the database",
|
|
err,
|
|
)
|
|
} else if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to find an environment with the specified identifier inside the database",
|
|
err,
|
|
)
|
|
}
|
|
|
|
namespace, err := request.RetrieveRouteVariableValue(r, "namespace")
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid namespace identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
var payload models.K8sIngressControllers
|
|
err = request.DecodeAndValidateJSONPayload(r, &payload)
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid request payload",
|
|
err,
|
|
)
|
|
}
|
|
|
|
existingClasses := endpoint.Kubernetes.Configuration.IngressClasses
|
|
var updatedClasses []portainer.KubernetesIngressClassConfig
|
|
PayloadLoop:
|
|
for _, p := range payload {
|
|
for _, existingClass := range existingClasses {
|
|
if p.ClassName != existingClass.Name {
|
|
continue
|
|
}
|
|
var updatedClass portainer.KubernetesIngressClassConfig
|
|
updatedClass.Name = existingClass.Name
|
|
updatedClass.Type = existingClass.Type
|
|
updatedClass.GloballyBlocked = existingClass.GloballyBlocked
|
|
|
|
// Handle "allow"
|
|
if p.Availability {
|
|
// remove the namespace from the list of blocked namespaces
|
|
// in the existingClass.
|
|
for _, blockedNS := range existingClass.BlockedNamespaces {
|
|
if blockedNS != namespace {
|
|
updatedClass.BlockedNamespaces = append(updatedClass.BlockedNamespaces, blockedNS)
|
|
}
|
|
}
|
|
|
|
updatedClasses = append(updatedClasses, updatedClass)
|
|
continue PayloadLoop
|
|
}
|
|
|
|
// Handle "disallow"
|
|
// If it's meant to be blocked we need to add the current
|
|
// namespace. First, check if it's already in the
|
|
// BlockedNamespaces and if not we append it.
|
|
updatedClass.BlockedNamespaces = existingClass.BlockedNamespaces
|
|
for _, ns := range updatedClass.BlockedNamespaces {
|
|
if namespace == ns {
|
|
updatedClasses = append(updatedClasses, updatedClass)
|
|
continue PayloadLoop
|
|
}
|
|
}
|
|
updatedClass.BlockedNamespaces = append(
|
|
updatedClass.BlockedNamespaces,
|
|
namespace,
|
|
)
|
|
updatedClasses = append(updatedClasses, updatedClass)
|
|
}
|
|
}
|
|
|
|
// At this point it's possible we had an existing class which was globally
|
|
// blocked and thus not included in the payload. As a result it is not yet
|
|
// part of updatedClasses, but we MUST include it or we would remove the
|
|
// global block.
|
|
for _, existingClass := range existingClasses {
|
|
var found bool
|
|
|
|
for _, updatedClass := range updatedClasses {
|
|
if existingClass.Name == updatedClass.Name {
|
|
found = true
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
updatedClasses = append(updatedClasses, existingClass)
|
|
}
|
|
}
|
|
|
|
endpoint.Kubernetes.Configuration.IngressClasses = updatedClasses
|
|
err = handler.DataStore.Endpoint().UpdateEndpoint(
|
|
portainer.EndpointID(endpointID),
|
|
endpoint,
|
|
)
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to update the BlockedIngressClasses inside the database",
|
|
err,
|
|
)
|
|
}
|
|
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 {
|
|
return httperror.BadRequest(
|
|
"Invalid namespace identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid environment identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
cli, ok := handler.KubernetesClientFactory.GetProxyKubeClient(
|
|
strconv.Itoa(endpointID), r.Header.Get("Authorization"),
|
|
)
|
|
if !ok {
|
|
return httperror.InternalServerError(
|
|
"Failed to lookup KubeClient",
|
|
nil,
|
|
)
|
|
}
|
|
|
|
ingresses, err := cli.GetIngresses(namespace)
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to retrieve ingresses",
|
|
err,
|
|
)
|
|
}
|
|
|
|
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 {
|
|
return httperror.BadRequest(
|
|
"Invalid namespace identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
var payload models.K8sIngressInfo
|
|
err = request.DecodeAndValidateJSONPayload(r, &payload)
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid request payload",
|
|
err,
|
|
)
|
|
}
|
|
|
|
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid environment identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
owner := "admin"
|
|
tokenData, err := security.RetrieveTokenData(r)
|
|
if err == nil && tokenData != nil {
|
|
owner = tokenData.Username
|
|
}
|
|
|
|
cli, ok := handler.KubernetesClientFactory.GetProxyKubeClient(
|
|
strconv.Itoa(endpointID), r.Header.Get("Authorization"),
|
|
)
|
|
if !ok {
|
|
return httperror.InternalServerError(
|
|
"Failed to lookup KubeClient",
|
|
nil,
|
|
)
|
|
}
|
|
|
|
err = cli.CreateIngress(namespace, payload, owner)
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to retrieve the ingress",
|
|
err,
|
|
)
|
|
}
|
|
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 {
|
|
return httperror.BadRequest(
|
|
"Invalid environment identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
cli, ok := handler.KubernetesClientFactory.GetProxyKubeClient(
|
|
strconv.Itoa(endpointID), r.Header.Get("Authorization"),
|
|
)
|
|
if !ok {
|
|
return httperror.InternalServerError(
|
|
"Failed to lookup KubeClient",
|
|
nil,
|
|
)
|
|
}
|
|
|
|
var payload models.K8sIngressDeleteRequests
|
|
err = request.DecodeAndValidateJSONPayload(r, &payload)
|
|
if err != nil {
|
|
return httperror.BadRequest("Invalid request payload", err)
|
|
}
|
|
|
|
err = cli.DeleteIngresses(payload)
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to delete ingresses",
|
|
err,
|
|
)
|
|
}
|
|
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 {
|
|
return httperror.BadRequest(
|
|
"Invalid namespace identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
var payload models.K8sIngressInfo
|
|
err = request.DecodeAndValidateJSONPayload(r, &payload)
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid request payload",
|
|
err,
|
|
)
|
|
}
|
|
|
|
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
|
if err != nil {
|
|
return httperror.BadRequest(
|
|
"Invalid environment identifier route variable",
|
|
err,
|
|
)
|
|
}
|
|
|
|
cli, ok := handler.KubernetesClientFactory.GetProxyKubeClient(
|
|
strconv.Itoa(endpointID), r.Header.Get("Authorization"),
|
|
)
|
|
if !ok {
|
|
return httperror.InternalServerError(
|
|
"Failed to lookup KubeClient",
|
|
nil,
|
|
)
|
|
}
|
|
|
|
err = cli.UpdateIngress(namespace, payload)
|
|
if err != nil {
|
|
return httperror.InternalServerError(
|
|
"Unable to update the ingress",
|
|
err,
|
|
)
|
|
}
|
|
return response.Empty(w)
|
|
}
|