Sfoglia il codice sorgente

Merge pull request #2279 from porter-dev/nafees/cli-improvements

[POR-641] New CLI commands to update env groups
abelanger5 3 anni fa
parent
commit
c6113862b6

+ 2 - 2
api/client/k8s.go

@@ -104,8 +104,8 @@ func (c *Client) GetEnvGroup(
 	projectID, clusterID uint,
 	namespace string,
 	req *types.GetEnvGroupRequest,
-) (*types.EnvGroup, error) {
-	resp := &types.EnvGroup{}
+) (*types.GetEnvGroupResponse, error) {
+	resp := &types.GetEnvGroupResponse{}
 
 	err := c.getRequest(
 		fmt.Sprintf(

+ 0 - 1
api/server/handlers/namespace/get_env_group.go

@@ -68,7 +68,6 @@ func (c *GetEnvGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	stackId, err := stacks.GetStackForEnvGroup(c.Config(), cluster.ProjectID, cluster.ID, envGroup)
 
 	if err != nil {
-
 		if errors.Is(err, gorm.ErrRecordNotFound) {
 			c.WriteResult(w, r, &types.GetEnvGroupResponse{EnvGroup: envGroup})
 			return

+ 2 - 2
cli/cmd/delete.go

@@ -32,7 +32,7 @@ deleting a configuration:
 		color.New(color.FgGreen, color.Bold).Sprintf("porter delete"),
 	),
 	Run: func(cmd *cobra.Command, args []string) {
-		err := checkLoginAndRun(args, delete)
+		err := checkLoginAndRun(args, deleteDeployment)
 
 		if err != nil {
 			os.Exit(1)
@@ -100,7 +100,7 @@ func init() {
 	rootCmd.AddCommand(deleteCmd)
 }
 
-func delete(_ *types.GetAuthenticatedUserResponse, client *api.Client, args []string) error {
+func deleteDeployment(_ *types.GetAuthenticatedUserResponse, client *api.Client, args []string) error {
 	projectID := cliConf.Project
 
 	if projectID == 0 {

+ 187 - 3
cli/cmd/deploy.go

@@ -1,11 +1,14 @@
 package cmd
 
 import (
+	"context"
 	"fmt"
 	"os"
 	"path/filepath"
 	"strings"
+	"time"
 
+	"github.com/briandowns/spinner"
 	"github.com/fatih/color"
 	api "github.com/porter-dev/porter/api/client"
 	"github.com/porter-dev/porter/api/types"
@@ -203,6 +206,39 @@ the image that the application uses if no --values file is specified:
 	},
 }
 
+var updateEnvGroupCmd = &cobra.Command{
+	Use:     "env-group",
+	Aliases: []string{"eg", "envgroup", "env-groups", "envgroups"},
+	Short:   "Updates an environment group's variables, specified by the --name flag.",
+	Run: func(cmd *cobra.Command, args []string) {
+		color.New(color.FgRed).Println("need to specify an operation to continue")
+	},
+}
+
+var updateSetEnvGroupCmd = &cobra.Command{
+	Use:   "set",
+	Short: "Sets the desired value of an environment variable in an env group in the form VAR=VALUE.",
+	Run: func(cmd *cobra.Command, args []string) {
+		err := checkLoginAndRun(args, updateSetEnvGroup)
+
+		if err != nil {
+			os.Exit(1)
+		}
+	},
+}
+
+var updateUnsetEnvGroupCmd = &cobra.Command{
+	Use:   "unset",
+	Short: "Removes an environment variable from an env group.",
+	Run: func(cmd *cobra.Command, args []string) {
+		err := checkLoginAndRun(args, updateUnsetEnvGroup)
+
+		if err != nil {
+			os.Exit(1)
+		}
+	},
+}
+
 var app string
 var getEnvFileDest string
 var localPath string
@@ -213,10 +249,12 @@ var stream bool
 var buildFlagsEnv []string
 var forcePush bool
 var useCache bool
+var value string
+var version uint
+var varType string
 
 func init() {
 	buildFlagsEnv = []string{}
-
 	rootCmd.AddCommand(updateCmd)
 
 	updateCmd.PersistentFlags().StringVar(
@@ -226,8 +264,6 @@ func init() {
 		"Application in the Porter dashboard",
 	)
 
-	updateCmd.MarkPersistentFlagRequired("app")
-
 	updateCmd.PersistentFlags().BoolVar(
 		&useCache,
 		"use-cache",
@@ -329,9 +365,44 @@ func init() {
 		"file destination for .env files",
 	)
 
+	updateGetEnvCmd.MarkPersistentFlagRequired("app")
+
+	updateBuildCmd.MarkPersistentFlagRequired("app")
+
+	updatePushCmd.MarkPersistentFlagRequired("app")
+
+	updateConfigCmd.MarkPersistentFlagRequired("app")
+
+	updateEnvGroupCmd.PersistentFlags().StringVar(
+		&name,
+		"name",
+		"",
+		"the name of the environment group",
+	)
+
+	updateEnvGroupCmd.PersistentFlags().UintVar(
+		&version,
+		"version",
+		0,
+		"the version of the environment group",
+	)
+
+	updateEnvGroupCmd.MarkPersistentFlagRequired("name")
+
+	updateSetEnvGroupCmd.PersistentFlags().StringVar(
+		&varType,
+		"type",
+		"normal",
+		"the type of environment variable (either \"normal\" or \"secret\")",
+	)
+
+	updateEnvGroupCmd.AddCommand(updateSetEnvGroupCmd)
+	updateEnvGroupCmd.AddCommand(updateUnsetEnvGroupCmd)
+
 	updateCmd.AddCommand(updateBuildCmd)
 	updateCmd.AddCommand(updatePushCmd)
 	updateCmd.AddCommand(updateConfigCmd)
+	updateCmd.AddCommand(updateEnvGroupCmd)
 }
 
 func updateFull(_ *types.GetAuthenticatedUserResponse, client *api.Client, args []string) error {
@@ -438,6 +509,119 @@ func updateUpgrade(_ *types.GetAuthenticatedUserResponse, client *api.Client, ar
 	return updateUpgradeWithAgent(updateAgent)
 }
 
+func updateSetEnvGroup(_ *types.GetAuthenticatedUserResponse, client *api.Client, args []string) error {
+	if len(args) == 0 {
+		return fmt.Errorf("required variable in the form of VAR=VALUE")
+	}
+
+	key, value, found := strings.Cut(args[0], "=")
+
+	if !found {
+		return fmt.Errorf("variable should be in the form of VAR=VALUE")
+	}
+
+	s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
+	s.Color("cyan")
+
+	s.Suffix = fmt.Sprintf(" Fetching env group '%s' in namespace '%s'", name, namespace)
+	s.Start()
+
+	envGroupResp, err := client.GetEnvGroup(context.Background(), cliConf.Project, cliConf.Cluster, namespace,
+		&types.GetEnvGroupRequest{
+			Name: name, Version: version,
+		},
+	)
+
+	s.Stop()
+
+	if err != nil {
+		return err
+	}
+
+	newEnvGroup := &types.CreateEnvGroupRequest{
+		Name:      envGroupResp.Name,
+		Variables: envGroupResp.Variables,
+	}
+
+	delete(newEnvGroup.Variables, key)
+
+	if varType == "secret" {
+		newEnvGroup.SecretVariables = make(map[string]string)
+		newEnvGroup.SecretVariables[key] = value
+
+		s.Suffix = fmt.Sprintf(" Adding new secret variable '%s' to env group '%s' in namespace '%s'", key, name, namespace)
+	} else {
+		newEnvGroup.Variables[key] = value
+
+		s.Suffix = fmt.Sprintf(" Adding new variable '%s' to env group '%s' in namespace '%s'", key, name, namespace)
+	}
+
+	s.Start()
+
+	_, err = client.CreateEnvGroup(
+		context.Background(), cliConf.Project, cliConf.Cluster, namespace, newEnvGroup,
+	)
+
+	s.Stop()
+
+	if err != nil {
+		return err
+	}
+
+	color.New(color.FgGreen).Println("env group successfully updated")
+
+	return nil
+}
+
+func updateUnsetEnvGroup(_ *types.GetAuthenticatedUserResponse, client *api.Client, args []string) error {
+	if len(args) == 0 {
+		return fmt.Errorf("required variable name")
+	}
+
+	s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
+	s.Color("cyan")
+
+	s.Suffix = fmt.Sprintf(" Fetching env group '%s' in namespace '%s'", name, namespace)
+	s.Start()
+
+	envGroupResp, err := client.GetEnvGroup(context.Background(), cliConf.Project, cliConf.Cluster, namespace,
+		&types.GetEnvGroupRequest{
+			Name: name, Version: version,
+		},
+	)
+
+	s.Stop()
+
+	if err != nil {
+		return err
+	}
+
+	newEnvGroup := &types.CreateEnvGroupRequest{
+		Name:      envGroupResp.Name,
+		Variables: envGroupResp.Variables,
+	}
+
+	delete(newEnvGroup.Variables, args[0])
+
+	s.Suffix = fmt.Sprintf(" Removing variable '%s' from env group '%s' in namespace '%s'", args[0], name, namespace)
+
+	s.Start()
+
+	_, err = client.CreateEnvGroup(
+		context.Background(), cliConf.Project, cliConf.Cluster, namespace, newEnvGroup,
+	)
+
+	s.Stop()
+
+	if err != nil {
+		return err
+	}
+
+	color.New(color.FgGreen).Println("env group successfully updated")
+
+	return nil
+}
+
 // HELPER METHODS
 func updateGetAgent(client *api.Client) (*deploy.DeployAgent, error) {
 	var buildMethod deploy.DeployBuildType

+ 10 - 4
cli/cmd/preview/env_group_driver.go

@@ -67,7 +67,7 @@ func (d *EnvGroupDriver) Apply(resource *models.Resource) (*models.Resource, err
 			group.Namespace = d.target.Namespace
 		}
 
-		envGroup, err := client.GetEnvGroup(
+		envGroupResp, err := client.GetEnvGroup(
 			context.Background(),
 			d.target.Project,
 			d.target.Cluster,
@@ -78,7 +78,7 @@ func (d *EnvGroupDriver) Apply(resource *models.Resource) (*models.Resource, err
 		)
 
 		if err != nil && err.Error() == "env group not found" {
-			envGroup, err = client.CreateEnvGroup(
+			newEnvGroup, err := client.CreateEnvGroup(
 				context.Background(), d.target.Project, d.target.Cluster, group.Namespace,
 				&types.CreateEnvGroupRequest{
 					Name:      group.Name,
@@ -89,12 +89,18 @@ func (d *EnvGroupDriver) Apply(resource *models.Resource) (*models.Resource, err
 			if err != nil {
 				return nil, err
 			}
+
+			envGroupResp = &types.GetEnvGroupResponse{
+				EnvGroup: &types.EnvGroup{
+					Variables: newEnvGroup.Variables,
+				},
+			}
 		} else if err != nil {
 			return nil, err
 		}
 
-		d.output[envGroup.Name] = map[string]interface{}{
-			"variables": envGroup.Variables,
+		d.output[envGroupResp.Name] = map[string]interface{}{
+			"variables": envGroupResp.Variables,
 		}
 	}
 

+ 4 - 0
internal/kubernetes/envgroup/create.go

@@ -85,6 +85,10 @@ func CreateEnvGroup(agent *kubernetes.Agent, input types.ConfigMapInput) (*v1.Co
 
 	oldSecret, _, err := agent.GetLatestVersionedSecret(input.Name, input.Namespace)
 
+	if input.SecretVariables == nil {
+		input.SecretVariables = make(map[string]string)
+	}
+
 	if err != nil && !errors.Is(err, kubernetes.IsNotFoundError) {
 		return nil, err
 	} else if err == nil && oldSecret != nil {