stack.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. package cmd
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. v2 "github.com/porter-dev/porter/cli/cmd/v2"
  7. "github.com/fatih/color"
  8. api "github.com/porter-dev/porter/api/client"
  9. "github.com/porter-dev/porter/api/types"
  10. "github.com/spf13/cobra"
  11. )
  12. var linkedApps []string
  13. // stackCmd represents the "porter stack" base command when called
  14. // without any subcommands
  15. var stackCmd = &cobra.Command{
  16. Use: "stack",
  17. Aliases: []string{"stacks"},
  18. Short: "Commands that control Porter Stacks",
  19. }
  20. var stackEnvGroupCmd = &cobra.Command{
  21. Use: "env-group",
  22. Aliases: []string{"eg", "envgroup", "env-groups", "envgroups"},
  23. Short: "Commands to add or remove an env group in a stack",
  24. Run: func(cmd *cobra.Command, args []string) {
  25. color.New(color.FgRed).Fprintln(os.Stderr, "need to specify an operation to continue")
  26. },
  27. }
  28. var stackEnvGroupAddCmd = &cobra.Command{
  29. Use: "add [name]",
  30. Args: cobra.ExactArgs(1),
  31. Short: "Add an env group to a stack",
  32. Run: func(cmd *cobra.Command, args []string) {
  33. err := checkLoginAndRun(args, stackAddEnvGroup)
  34. if err != nil {
  35. os.Exit(1)
  36. }
  37. },
  38. }
  39. var stackEnvGroupRemoveCmd = &cobra.Command{
  40. Use: "remove [name]",
  41. Args: cobra.ExactArgs(1),
  42. Short: "Remove an existing env group from a stack",
  43. Run: func(cmd *cobra.Command, args []string) {
  44. err := checkLoginAndRun(args, stackRemoveEnvGroup)
  45. if err != nil {
  46. os.Exit(1)
  47. }
  48. },
  49. }
  50. func init() {
  51. rootCmd.AddCommand(stackCmd)
  52. stackCmd.AddCommand(stackEnvGroupCmd)
  53. stackCmd.PersistentFlags().StringVar(
  54. &name,
  55. "name",
  56. "",
  57. "the name of the stack",
  58. )
  59. stackCmd.PersistentFlags().StringVar(
  60. &namespace,
  61. "namespace",
  62. "default",
  63. "the namespace of the stack",
  64. )
  65. stackEnvGroupAddCmd.PersistentFlags().StringArrayVarP(
  66. &normalEnvGroupVars,
  67. "normal",
  68. "n",
  69. []string{},
  70. "list of variables to set, in the form VAR=VALUE",
  71. )
  72. stackEnvGroupAddCmd.PersistentFlags().StringArrayVarP(
  73. &secretEnvGroupVars,
  74. "secret",
  75. "s",
  76. []string{},
  77. "list of secret variables to set, in the form VAR=VALUE",
  78. )
  79. stackEnvGroupAddCmd.PersistentFlags().StringArrayVar(
  80. &linkedApps,
  81. "linked-apps",
  82. []string{},
  83. "list of stack apps to link this env group with",
  84. )
  85. stackEnvGroupCmd.AddCommand(stackEnvGroupAddCmd)
  86. stackEnvGroupCmd.AddCommand(stackEnvGroupRemoveCmd)
  87. }
  88. func stackAddEnvGroup(_ *types.GetAuthenticatedUserResponse, client *api.Client, args []string) error {
  89. ctx := context.Background()
  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(context.Background(), 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. context.Background(), 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(_ *types.GetAuthenticatedUserResponse, client *api.Client, args []string) error {
  155. ctx := context.Background()
  156. project, err := client.GetProject(ctx, cliConf.Project)
  157. if err != nil {
  158. return fmt.Errorf("could not retrieve project from Porter API. Please contact support@porter.run")
  159. }
  160. if project.ValidateApplyV2 {
  161. err = v2.StackRemoveEnvGroup(ctx)
  162. if err != nil {
  163. return err
  164. }
  165. return nil
  166. }
  167. envGroupName := args[0]
  168. if len(envGroupName) == 0 {
  169. return fmt.Errorf("empty env group name")
  170. } else if len(name) == 0 {
  171. return fmt.Errorf("empty stack name")
  172. }
  173. listStacks, err := client.ListStacks(context.Background(), cliConf.Project, cliConf.Cluster, namespace)
  174. if err != nil {
  175. return err
  176. }
  177. stacks := *listStacks
  178. var stackID string
  179. for _, stk := range stacks {
  180. if stk.Name == name {
  181. stackID = stk.ID
  182. }
  183. }
  184. if len(stackID) == 0 {
  185. return fmt.Errorf("stack not found")
  186. }
  187. err = client.RemoveEnvGroupFromStack(context.Background(), cliConf.Project, cliConf.Cluster, namespace, stackID,
  188. envGroupName)
  189. if err != nil {
  190. return err
  191. }
  192. color.New(color.FgGreen).Println("successfully removed env group")
  193. return nil
  194. }