Browse Source

server: add HandleRenameConfigMap

Anukul Sangwan 4 years ago
parent
commit
918e667a05
4 changed files with 115 additions and 0 deletions
  1. 6 0
      internal/forms/k8s.go
  2. 9 0
      internal/kubernetes/agent.go
  3. 86 0
      server/api/k8s_handler.go
  4. 14 0
      server/router/router.go

+ 6 - 0
internal/forms/k8s.go

@@ -45,6 +45,12 @@ type ConfigMapForm struct {
 	SecretEnvVariables map[string]string `json:"secret_variables"`
 }
 
+type RenameConfigMapForm struct {
+	Name      string `json:"name" form:"required"`
+	Namespace string `json:"namespace" form:"required"`
+	NewName   string `json:"new_name" form:"required"`
+}
+
 type NamespaceForm struct {
 	Name string `json:"name" form:"required"`
 }

+ 9 - 0
internal/kubernetes/agent.go

@@ -210,6 +210,15 @@ func (a *Agent) GetConfigMap(name string, namespace string) (*v1.ConfigMap, erro
 	)
 }
 
+// GetSecret retrieves the secret given its name and namespace
+func (a *Agent) GetSecret(name string, namespace string) (*v1.Secret, error) {
+	return a.Clientset.CoreV1().Secrets(namespace).Get(
+		context.TODO(),
+		name,
+		metav1.GetOptions{},
+	)
+}
+
 // ListConfigMaps simply lists namespaces
 func (a *Agent) ListConfigMaps(namespace string) (*v1.ConfigMapList, error) {
 	return a.Clientset.CoreV1().ConfigMaps(namespace).List(

+ 86 - 0
server/api/k8s_handler.go

@@ -565,6 +565,92 @@ func (app *App) HandleUpdateConfigMap(w http.ResponseWriter, r *http.Request) {
 	return
 }
 
+// HandleRenameConfigMap renames the configmap name given the current name, namespace and new name.
+func (app *App) HandleRenameConfigMap(w http.ResponseWriter, r *http.Request) {
+	vals, err := url.ParseQuery(r.URL.RawQuery)
+
+	if err != nil {
+		app.handleErrorFormDecoding(err, ErrReleaseDecode, w)
+		return
+	}
+
+	// get the filter options
+	form := &forms.K8sForm{
+		OutOfClusterConfig: &kubernetes.OutOfClusterConfig{
+			Repo:              app.Repo,
+			DigitalOceanOAuth: app.DOConf,
+		},
+	}
+
+	form.PopulateK8sOptionsFromQueryParams(vals, app.Repo.Cluster)
+
+	// validate the form
+	if err := app.validator.Struct(form); err != nil {
+		app.handleErrorFormValidation(err, ErrK8sValidate, w)
+		return
+	}
+
+	// create a new agent
+	var agent *kubernetes.Agent
+
+	if app.ServerConf.IsTesting {
+		agent = app.TestAgents.K8sAgent
+	} else {
+		agent, err = kubernetes.GetAgentOutOfClusterConfig(form.OutOfClusterConfig)
+	}
+
+	renameConfigMapForm := &forms.RenameConfigMapForm{}
+
+	if err := json.NewDecoder(r.Body).Decode(renameConfigMapForm); err != nil {
+		app.handleErrorFormDecoding(err, ErrEnvDecode, w)
+		return
+	}
+
+	configMap, err := agent.GetConfigMap(renameConfigMapForm.Name, renameConfigMapForm.Namespace)
+
+	if err != nil {
+		app.handleErrorInternal(err, w)
+		return
+	}
+
+	secret, err := agent.GetSecret(configMap.Name, configMap.Namespace)
+
+	if err != nil {
+		app.handleErrorInternal(err, w)
+		return
+	}
+
+	var decodedSecretData = make(map[string]string)
+	for k, v := range secret.Data {
+		decodedSecretData[k] = string(v)
+	}
+
+	if err := deleteConfigMap(agent, configMap.Name, configMap.Namespace); err != nil {
+		app.handleErrorInternal(err, w)
+		return
+	}
+
+	newConfigMap := &forms.ConfigMapForm{
+		Name:               renameConfigMapForm.NewName,
+		Namespace:          configMap.Namespace,
+		EnvVariables:       configMap.Data,
+		SecretEnvVariables: decodedSecretData,
+	}
+
+	if err := createConfigMap(agent, newConfigMap); err != nil {
+		app.handleErrorInternal(err, w)
+		return
+	}
+
+	if err := json.NewEncoder(w).Encode(newConfigMap); err != nil {
+		app.handleErrorFormDecoding(err, ErrEnvDecode, w)
+		return
+	}
+
+	w.WriteHeader(http.StatusOK)
+	return
+}
+
 // HandleGetPodLogs returns real-time logs of the pod via websockets
 // TODO: Refactor repeated calls.
 func (app *App) HandleGetPodLogs(w http.ResponseWriter, r *http.Request) {

+ 14 - 0
server/router/router.go

@@ -1543,6 +1543,20 @@ func New(a *api.App) *chi.Mux {
 				),
 			)
 
+			r.Method(
+				"POST",
+				"/projects/{project_id}/k8s/configmap/rename",
+				auth.DoesUserHaveProjectAccess(
+					auth.DoesUserHaveClusterAccess(
+						requestlog.NewHandler(a.HandleRenameConfigMap, l),
+						mw.URLParam,
+						mw.QueryParam,
+					),
+					mw.URLParam,
+					mw.WriteAccess,
+				),
+			)
+
 			r.Method(
 				"DELETE",
 				"/projects/{project_id}/k8s/jobs/{namespace}/{name}",