stack.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package cmd
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "github.com/porter-dev/porter/cli/cmd/config"
  7. v2 "github.com/porter-dev/porter/cli/cmd/v2"
  8. "github.com/fatih/color"
  9. api "github.com/porter-dev/porter/api/client"
  10. "github.com/porter-dev/porter/api/types"
  11. "github.com/spf13/cobra"
  12. )
  13. var linkedApps []string
  14. // stackCmd represents the "porter stack" base command when called
  15. // without any subcommands
  16. var stackCmd = &cobra.Command{
  17. Use: "stack",
  18. Aliases: []string{"stacks"},
  19. Short: "Commands that control Porter Stacks",
  20. }
  21. var stackEnvGroupCmd = &cobra.Command{
  22. Use: "env-group",
  23. Aliases: []string{"eg", "envgroup", "env-groups", "envgroups"},
  24. Short: "Commands to add or remove an env group in a stack",
  25. Run: func(cmd *cobra.Command, args []string) {
  26. color.New(color.FgRed).Fprintln(os.Stderr, "need to specify an operation to continue")
  27. },
  28. }
  29. var stackEnvGroupAddCmd = &cobra.Command{
  30. Use: "add [name]",
  31. Args: cobra.ExactArgs(1),
  32. Short: "Add an env group to a stack",
  33. Run: func(cmd *cobra.Command, args []string) {
  34. err := checkLoginAndRun(cmd.Context(), args, stackAddEnvGroup)
  35. if err != nil {
  36. os.Exit(1)
  37. }
  38. },
  39. }
  40. var stackEnvGroupRemoveCmd = &cobra.Command{
  41. Use: "remove [name]",
  42. Args: cobra.ExactArgs(1),
  43. Short: "Remove an existing env group from a stack",
  44. Run: func(cmd *cobra.Command, args []string) {
  45. err := checkLoginAndRun(cmd.Context(), args, stackRemoveEnvGroup)
  46. if err != nil {
  47. os.Exit(1)
  48. }
  49. },
  50. }
  51. func init() {
  52. rootCmd.AddCommand(stackCmd)
  53. stackCmd.AddCommand(stackEnvGroupCmd)
  54. stackCmd.PersistentFlags().StringVar(
  55. &name,
  56. "name",
  57. "",
  58. "the name of the stack",
  59. )
  60. stackCmd.PersistentFlags().StringVar(
  61. &namespace,
  62. "namespace",
  63. "default",
  64. "the namespace of the stack",
  65. )
  66. stackEnvGroupAddCmd.PersistentFlags().StringArrayVarP(
  67. &normalEnvGroupVars,
  68. "normal",
  69. "n",
  70. []string{},
  71. "list of variables to set, in the form VAR=VALUE",
  72. )
  73. stackEnvGroupAddCmd.PersistentFlags().StringArrayVarP(
  74. &secretEnvGroupVars,
  75. "secret",
  76. "s",
  77. []string{},
  78. "list of secret variables to set, in the form VAR=VALUE",
  79. )
  80. stackEnvGroupAddCmd.PersistentFlags().StringArrayVar(
  81. &linkedApps,
  82. "linked-apps",
  83. []string{},
  84. "list of stack apps to link this env group with",
  85. )
  86. stackEnvGroupCmd.AddCommand(stackEnvGroupAddCmd)
  87. stackEnvGroupCmd.AddCommand(stackEnvGroupRemoveCmd)
  88. }
  89. func stackAddEnvGroup(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConf config.CLIConfig, args []string) error {
  90. project, err := client.GetProject(ctx, cliConf.Project)
  91. if err != nil {
  92. return fmt.Errorf("could not retrieve project from Porter API. Please contact support@porter.run")
  93. }
  94. if project.ValidateApplyV2 {
  95. err = v2.StackAddEnvGroup(ctx)
  96. if err != nil {
  97. return err
  98. }
  99. return nil
  100. }
  101. envGroupName := args[0]
  102. if len(envGroupName) == 0 {
  103. return fmt.Errorf("empty env group name")
  104. } else if len(name) == 0 {
  105. return fmt.Errorf("empty stack name")
  106. } else if len(normalEnvGroupVars) == 0 && len(secretEnvGroupVars) == 0 {
  107. return fmt.Errorf("one or more variables are required to create the env group")
  108. }
  109. listStacks, err := client.ListStacks(ctx, cliConf.Project, cliConf.Cluster, namespace)
  110. if err != nil {
  111. return err
  112. }
  113. stacks := *listStacks
  114. var stackID string
  115. for _, stk := range stacks {
  116. if stk.Name == name {
  117. stackID = stk.ID
  118. }
  119. }
  120. if len(stackID) == 0 {
  121. return fmt.Errorf("stack not found")
  122. }
  123. normalVariables := make(map[string]string)
  124. secretVariables := make(map[string]string)
  125. for _, v := range normalEnvGroupVars {
  126. key, val, err := validateVarValue(v)
  127. if err != nil {
  128. return err
  129. }
  130. normalVariables[key] = val
  131. }
  132. for _, v := range secretEnvGroupVars {
  133. key, val, err := validateVarValue(v)
  134. if err != nil {
  135. return err
  136. }
  137. secretVariables[key] = val
  138. }
  139. err = client.AddEnvGroupToStack(
  140. ctx, cliConf.Project, cliConf.Cluster, namespace, stackID,
  141. &types.CreateStackEnvGroupRequest{
  142. Name: envGroupName,
  143. Variables: normalVariables,
  144. SecretVariables: secretVariables,
  145. LinkedApplications: linkedApps,
  146. },
  147. )
  148. if err != nil {
  149. return err
  150. }
  151. color.New(color.FgGreen).Println("successfully added env group")
  152. return nil
  153. }
  154. func stackRemoveEnvGroup(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConf config.CLIConfig, args []string) error {
  155. project, err := client.GetProject(ctx, cliConf.Project)
  156. if err != nil {
  157. return fmt.Errorf("could not retrieve project from Porter API. Please contact support@porter.run")
  158. }
  159. if project.ValidateApplyV2 {
  160. err = v2.StackRemoveEnvGroup(ctx)
  161. if err != nil {
  162. return err
  163. }
  164. return nil
  165. }
  166. envGroupName := args[0]
  167. if len(envGroupName) == 0 {
  168. return fmt.Errorf("empty env group name")
  169. } else if len(name) == 0 {
  170. return fmt.Errorf("empty stack name")
  171. }
  172. listStacks, err := client.ListStacks(ctx, cliConf.Project, cliConf.Cluster, namespace)
  173. if err != nil {
  174. return err
  175. }
  176. stacks := *listStacks
  177. var stackID string
  178. for _, stk := range stacks {
  179. if stk.Name == name {
  180. stackID = stk.ID
  181. }
  182. }
  183. if len(stackID) == 0 {
  184. return fmt.Errorf("stack not found")
  185. }
  186. err = client.RemoveEnvGroupFromStack(ctx, cliConf.Project, cliConf.Cluster, namespace, stackID,
  187. envGroupName)
  188. if err != nil {
  189. return err
  190. }
  191. color.New(color.FgGreen).Println("successfully removed env group")
  192. return nil
  193. }