Kaynağa Gözat

add NewRenameConfigMapHandler and NewDeleteConfigMapHandler

Anukul Sangwan 4 yıl önce
ebeveyn
işleme
54ee051647

+ 12 - 7
api/server/handlers/namespace/create_configmap.go

@@ -49,7 +49,12 @@ func (c *CreateConfigMapHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		return
 	}
 
-	configMap, err := createConfigMap(agent, namespace, request)
+	configMap, err := createConfigMap(agent, types.ConfigMapInput{
+		Name:            request.Name,
+		Namespace:       namespace,
+		Variables:       request.Variables,
+		SecretVariables: request.SecretVariables,
+	})
 
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
@@ -63,10 +68,10 @@ func (c *CreateConfigMapHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 	c.WriteResult(w, r, res)
 }
 
-func createConfigMap(agent *kubernetes.Agent, namespace string, request *types.CreateConfigMapRequest) (*v1.ConfigMap, error) {
+func createConfigMap(agent *kubernetes.Agent, input types.ConfigMapInput) (*v1.ConfigMap, error) {
 	secretData := make(map[string][]byte)
 
-	for key, rawValue := range request.SecretVariables {
+	for key, rawValue := range input.SecretVariables {
 		// encodedValue := base64.StdEncoding.EncodeToString([]byte(rawValue))
 
 		// if err != nil {
@@ -78,14 +83,14 @@ func createConfigMap(agent *kubernetes.Agent, namespace string, request *types.C
 	}
 
 	// create secret first
-	if _, err := agent.CreateLinkedSecret(request.Name, namespace, request.Name, secretData); err != nil {
+	if _, err := agent.CreateLinkedSecret(input.Name, input.Namespace, input.Name, secretData); err != nil {
 		return nil, err
 	}
 
 	// add all secret env variables to configmap with value PORTERSECRET_${configmap_name}
-	for key := range request.SecretVariables {
-		request.Variables[key] = fmt.Sprintf("PORTERSECRET_%s", request.Name)
+	for key := range input.SecretVariables {
+		input.Variables[key] = fmt.Sprintf("PORTERSECRET_%s", input.Name)
 	}
 
-	return agent.CreateConfigMap(request.Name, namespace, request.Variables)
+	return agent.CreateConfigMap(input.Name, input.Namespace, input.Variables)
 }

+ 66 - 0
api/server/handlers/namespace/delete_configmap.go

@@ -0,0 +1,66 @@
+package namespace
+
+import (
+	"net/http"
+
+	"github.com/porter-dev/porter/api/server/authz"
+	"github.com/porter-dev/porter/api/server/handlers"
+	"github.com/porter-dev/porter/api/server/shared"
+	"github.com/porter-dev/porter/api/server/shared/apierrors"
+	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/kubernetes"
+	"github.com/porter-dev/porter/internal/models"
+)
+
+type DeleteConfigMapHandler struct {
+	handlers.PorterHandlerReader
+	authz.KubernetesAgentGetter
+}
+
+func NewDeleteConfigMapHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+) *DeleteConfigMapHandler {
+	return &DeleteConfigMapHandler{
+		PorterHandlerReader:   handlers.NewDefaultPorterHandler(config, decoderValidator, nil),
+		KubernetesAgentGetter: authz.NewOutOfClusterAgentGetter(config),
+	}
+}
+
+func (c *DeleteConfigMapHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	request := &types.DeleteConfigMapRequest{}
+
+	if ok := c.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	namespace := r.Context().Value(types.NamespaceScope).(string)
+	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
+
+	agent, err := c.GetAgent(r, cluster)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	if err := deleteConfigMap(agent, request.Name, namespace); err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	w.WriteHeader(http.StatusOK)
+}
+
+func deleteConfigMap(agent *kubernetes.Agent, name, namespace string) error {
+	if err := agent.DeleteLinkedSecret(name, namespace); err != nil {
+		return err
+	}
+
+	if err := agent.DeleteConfigMap(name, namespace); err != nil {
+		return err
+	}
+
+	return nil
+}

+ 93 - 0
api/server/handlers/namespace/rename_configmap.go

@@ -0,0 +1,93 @@
+package namespace
+
+import (
+	"net/http"
+
+	"github.com/porter-dev/porter/api/server/authz"
+	"github.com/porter-dev/porter/api/server/handlers"
+	"github.com/porter-dev/porter/api/server/shared"
+	"github.com/porter-dev/porter/api/server/shared/apierrors"
+	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/models"
+)
+
+type RenameConfigMapHandler struct {
+	handlers.PorterHandlerReadWriter
+	authz.KubernetesAgentGetter
+}
+
+func NewRenameConfigMapHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+	writer shared.ResultWriter,
+) *RenameConfigMapHandler {
+	return &RenameConfigMapHandler{
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
+		KubernetesAgentGetter:   authz.NewOutOfClusterAgentGetter(config),
+	}
+}
+
+func (c *RenameConfigMapHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	request := &types.RenameConfigMapRequest{}
+
+	if ok := c.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	if request.NewName == request.Name {
+		w.WriteHeader(http.StatusBadRequest)
+		return
+	}
+
+	namespace := r.Context().Value(types.NamespaceScope).(string)
+	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
+
+	agent, err := c.GetAgent(r, cluster)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	configMap, err := agent.GetConfigMap(request.Name, namespace)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	secret, err := agent.GetSecret(configMap.Name, configMap.Namespace)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	var decodedSecretData = make(map[string]string)
+	for k, v := range secret.Data {
+		decodedSecretData[k] = string(v)
+	}
+
+	newConfigMap, err := createConfigMap(agent, types.ConfigMapInput{
+		Name:            request.NewName,
+		Namespace:       namespace,
+		Variables:       configMap.Data,
+		SecretVariables: decodedSecretData,
+	})
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	if err := deleteConfigMap(agent, configMap.Name, configMap.Namespace); err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	res := types.RenameConfigMapResponse{
+		ConfigMap: newConfigMap,
+	}
+
+	c.WriteResult(w, r, res)
+}

+ 59 - 0
api/server/router/namespace.go

@@ -142,6 +142,65 @@ func getNamespaceRoutes(
 		Router:   r,
 	})
 
+	// POST /api/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/configmap/rename -> namespace.NewRenameConfigMapHandler
+	renameConfigMapEndpoint := factory.NewAPIEndpoint(
+		&types.APIRequestMetadata{
+			Verb:   types.APIVerbUpdate,
+			Method: types.HTTPVerbPost,
+			Path: &types.Path{
+				Parent:       basePath,
+				RelativePath: relPath + "/configmap/rename",
+			},
+			Scopes: []types.PermissionScope{
+				types.UserScope,
+				types.ProjectScope,
+				types.ClusterScope,
+				types.NamespaceScope,
+			},
+		},
+	)
+
+	renameConfigMapHandler := namespace.NewRenameConfigMapHandler(
+		config,
+		factory.GetDecoderValidator(),
+		factory.GetResultWriter(),
+	)
+
+	routes = append(routes, &Route{
+		Endpoint: renameConfigMapEndpoint,
+		Handler:  renameConfigMapHandler,
+		Router:   r,
+	})
+
+	// DELETE /api/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/configmap/delete -> namespace.NewDeleteConfigMapHandler
+	deleteConfigMapEndpoint := factory.NewAPIEndpoint(
+		&types.APIRequestMetadata{
+			Verb:   types.APIVerbDelete,
+			Method: types.HTTPVerbDelete,
+			Path: &types.Path{
+				Parent:       basePath,
+				RelativePath: relPath + "/configmap/delete",
+			},
+			Scopes: []types.PermissionScope{
+				types.UserScope,
+				types.ProjectScope,
+				types.ClusterScope,
+				types.NamespaceScope,
+			},
+		},
+	)
+
+	deleteConfigMapHandler := namespace.NewDeleteConfigMapHandler(
+		config,
+		factory.GetDecoderValidator(),
+	)
+
+	routes = append(routes, &Route{
+		Endpoint: deleteConfigMapEndpoint,
+		Handler:  deleteConfigMapHandler,
+		Router:   r,
+	})
+
 	// GET /api/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases -> namespace.NewListReleasesHandler
 	listReleasesEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{

+ 20 - 0
api/types/namespace.go

@@ -67,6 +67,13 @@ type ListConfigMapsResponse struct {
 	*v1.ConfigMapList
 }
 
+type ConfigMapInput struct {
+	Name            string
+	Namespace       string
+	Variables       map[string]string
+	SecretVariables map[string]string
+}
+
 type CreateConfigMapRequest struct {
 	Name            string            `json:"name,required"`
 	Variables       map[string]string `json:"variables,required"`
@@ -76,3 +83,16 @@ type CreateConfigMapRequest struct {
 type CreateConfigMapResponse struct {
 	*v1.ConfigMap
 }
+
+type RenameConfigMapRequest struct {
+	Name    string `json:"name,required"`
+	NewName string `json:"new_name,required"`
+}
+
+type RenameConfigMapResponse struct {
+	*v1.ConfigMap
+}
+
+type DeleteConfigMapRequest struct {
+	Name string `schema:"name,required"`
+}

+ 6 - 4
dashboard/src/main/home/cluster-dashboard/env-groups/ExpandedEnvGroup.tsx

@@ -123,12 +123,12 @@ class ExpandedEnvGroup extends Component<PropsType, StateType> {
         "<token>",
         {
           name,
-          namespace,
           new_name: newName,
         },
         {
           id: this.context.currentProject.id,
           cluster_id: this.props.currentCluster.id,
+          namespace,
         }
       )
       .then((res) => {
@@ -348,10 +348,12 @@ class ExpandedEnvGroup extends Component<PropsType, StateType> {
         "<token>",
         {
           name,
-          namespace,
-          cluster_id: this.props.currentCluster.id,
         },
-        { id: this.context.currentProject.id }
+        {
+          id: this.context.currentProject.id,
+          cluster_id: this.props.currentCluster.id,
+          namespace,
+        }
       )
       .then((res) => {
         this.props.closeExpanded();

+ 11 - 7
dashboard/src/shared/api.tsx

@@ -930,24 +930,28 @@ const updateConfigMap = baseApi<
 const renameConfigMap = baseApi<
   {
     name: string;
-    namespace: string;
     new_name: string;
   },
-  { id: number; cluster_id: number }
+  {
+    id: number;
+    cluster_id: number;
+    namespace: string;
+  }
 >("POST", (pathParams) => {
-  let { id, cluster_id } = pathParams;
-  return `/api/projects/${id}/k8s/configmap/rename?cluster_id=${cluster_id}`;
+  return `/api/projects/${pathParams.id}/clusters/${pathParams.cluster_id}/namespaces/${pathParams.namespace}/configmap/rename`;
 });
 
 const deleteConfigMap = baseApi<
   {
     name: string;
+  },
+  {
+    id: number;
     namespace: string;
     cluster_id: number;
-  },
-  { id: number }
+  }
 >("DELETE", (pathParams) => {
-  return `/api/projects/${pathParams.id}/k8s/configmap/delete`;
+  return `/api/projects/${pathParams.id}/clusters/${pathParams.cluster_id}/namespaces/${pathParams.namespace}/configmap/delete`;
 });
 
 const createNamespace = baseApi<

+ 2 - 2
docs/developing/backend-refactor-status.md

@@ -79,9 +79,9 @@
 | <li>- [ ] `GET /api/projects/{project_id}/invites/{token}`                                                                  |             |                 |             |                  |
 | <li>- [x] `GET /api/projects/{project_id}/k8s/configmap`                                                                    | AS          | yes             |             | yes              |
 | <li>- [x] `POST /api/projects/{project_id}/k8s/configmap/create`                                                            | AS          | yes             |             | yes              |
-| <li>- [ ] `DELETE /api/projects/{project_id}/k8s/configmap/delete`                                                          |             |                 |             |                  |
+| <li>- [x] `DELETE /api/projects/{project_id}/k8s/configmap/delete`                                                          | AS          | yes             |             | yes              |
 | <li>- [x] `GET /api/projects/{project_id}/k8s/configmap/list`                                                               | AS          | yes             |             | yes              |
-| <li>- [ ] `POST /api/projects/{project_id}/k8s/configmap/rename`                                                            |             |                 |             |                  |
+| <li>- [x] `POST /api/projects/{project_id}/k8s/configmap/rename`                                                            | AS          | yes             |             | yes              |
 | <li>- [ ] `POST /api/projects/{project_id}/k8s/configmap/update`                                                            |             |                 |             |                  |
 | <li>- [ ] `GET /api/projects/{project_id}/k8s/helm_releases`                                                                |             |                 |             |                  |
 | <li>- [ ] `DELETE /api/projects/{project_id}/k8s/jobs/{namespace}/{name}`                                                   |             |                 |             |                  |