config.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. package commands
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "strconv"
  8. "strings"
  9. "time"
  10. "github.com/briandowns/spinner"
  11. "github.com/fatih/color"
  12. api "github.com/porter-dev/porter/api/client"
  13. "github.com/porter-dev/porter/api/types"
  14. "github.com/porter-dev/porter/cli/cmd/config"
  15. "github.com/porter-dev/porter/cli/cmd/utils"
  16. "github.com/spf13/cobra"
  17. )
  18. func registerCommand_Config(cliConf config.CLIConfig) *cobra.Command {
  19. configCmd := &cobra.Command{
  20. Use: "config",
  21. Short: "Commands that control local configuration settings",
  22. Run: func(cmd *cobra.Command, args []string) {
  23. if err := printConfig(); err != nil {
  24. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %v\n", err)
  25. os.Exit(1)
  26. }
  27. },
  28. }
  29. configSetProjectCmd := &cobra.Command{
  30. Use: "set-project [id]",
  31. Args: cobra.MaximumNArgs(1),
  32. Short: "Saves the project id in the default configuration",
  33. Run: func(cmd *cobra.Command, args []string) {
  34. client, err := api.NewClientWithConfig(cmd.Context(), api.NewClientInput{
  35. BaseURL: fmt.Sprintf("%s/api", cliConf.Host),
  36. BearerToken: cliConf.Token,
  37. CookieFileName: "cookie.json",
  38. })
  39. if err != nil {
  40. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "error creating porter API client: %s\n", err.Error())
  41. os.Exit(1)
  42. }
  43. if len(args) == 0 {
  44. err := checkLoginAndRunWithConfig(cmd, cliConf, args, listAndSetProject)
  45. if err != nil {
  46. os.Exit(1)
  47. }
  48. } else {
  49. projID, err := strconv.ParseUint(args[0], 10, 64)
  50. if err != nil {
  51. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %s\n", err.Error())
  52. os.Exit(1)
  53. }
  54. err = cliConf.SetProject(cmd.Context(), client, uint(projID))
  55. if err != nil {
  56. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %s\n", err.Error())
  57. os.Exit(1)
  58. }
  59. }
  60. },
  61. }
  62. configSetClusterCmd := &cobra.Command{
  63. Use: "set-cluster [id]",
  64. Args: cobra.MaximumNArgs(1),
  65. Short: "Saves the cluster id in the default configuration",
  66. Run: func(cmd *cobra.Command, args []string) {
  67. if len(args) == 0 {
  68. err := checkLoginAndRunWithConfig(cmd, cliConf, args, listAndSetCluster)
  69. if err != nil {
  70. os.Exit(1)
  71. }
  72. } else {
  73. clusterID, err := strconv.ParseUint(args[0], 10, 64)
  74. if err != nil {
  75. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %v\n", err)
  76. os.Exit(1)
  77. }
  78. err = cliConf.SetCluster(uint(clusterID))
  79. if err != nil {
  80. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %v\n", err)
  81. os.Exit(1)
  82. }
  83. }
  84. },
  85. }
  86. configSetRegistryCmd := &cobra.Command{
  87. Use: "set-registry [id]",
  88. Args: cobra.MaximumNArgs(1),
  89. Short: "Saves the registry id in the default configuration",
  90. Run: func(cmd *cobra.Command, args []string) {
  91. if len(args) == 0 {
  92. err := checkLoginAndRunWithConfig(cmd, cliConf, args, listAndSetRegistry)
  93. if err != nil {
  94. os.Exit(1)
  95. }
  96. } else {
  97. registryID, err := strconv.ParseUint(args[0], 10, 64)
  98. if err != nil {
  99. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %v\n", err)
  100. os.Exit(1)
  101. }
  102. err = cliConf.SetRegistry(uint(registryID))
  103. if err != nil {
  104. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %v\n", err)
  105. os.Exit(1)
  106. }
  107. }
  108. },
  109. }
  110. configSetHelmRepoCmd := &cobra.Command{
  111. Use: "set-helmrepo [id]",
  112. Args: cobra.ExactArgs(1),
  113. Short: "Saves the helm repo id in the default configuration",
  114. Run: func(cmd *cobra.Command, args []string) {
  115. hrID, err := strconv.ParseUint(args[0], 10, 64)
  116. if err != nil {
  117. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %v\n", err)
  118. os.Exit(1)
  119. }
  120. err = cliConf.SetHelmRepo(uint(hrID))
  121. if err != nil {
  122. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %v\n", err)
  123. os.Exit(1)
  124. }
  125. },
  126. }
  127. configSetHostCmd := &cobra.Command{
  128. Use: "set-host [host]",
  129. Args: cobra.ExactArgs(1),
  130. Short: "Saves the host in the default configuration",
  131. Run: func(cmd *cobra.Command, args []string) {
  132. err := cliConf.SetHost(args[0])
  133. if err != nil {
  134. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %s\n", err.Error())
  135. os.Exit(1)
  136. }
  137. },
  138. }
  139. configSetKubeconfigCmd := &cobra.Command{
  140. Use: "set-kubeconfig [kubeconfig-path]",
  141. Args: cobra.ExactArgs(1),
  142. Short: "Saves the path to kubeconfig in the default configuration",
  143. Run: func(cmd *cobra.Command, args []string) {
  144. err := cliConf.SetKubeconfig(args[0])
  145. if err != nil {
  146. _, _ = color.New(color.FgRed).Fprintf(os.Stderr, "An error occurred: %s\n", err.Error())
  147. os.Exit(1)
  148. }
  149. },
  150. }
  151. configCmd.AddCommand(configSetProjectCmd)
  152. configCmd.AddCommand(configSetClusterCmd)
  153. configCmd.AddCommand(configSetHostCmd)
  154. configCmd.AddCommand(configSetRegistryCmd)
  155. configCmd.AddCommand(configSetHelmRepoCmd)
  156. configCmd.AddCommand(configSetKubeconfigCmd)
  157. return configCmd
  158. }
  159. func printConfig() error {
  160. config, err := os.ReadFile(filepath.Join(home, ".porter", "porter.yaml"))
  161. if err != nil {
  162. return err
  163. }
  164. fmt.Println(string(config))
  165. return nil
  166. }
  167. func listAndSetProject(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConf config.CLIConfig, featureFlags config.FeatureFlags, cmd *cobra.Command, args []string) error {
  168. s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
  169. _ = s.Color("cyan")
  170. s.Suffix = " Loading list of projects"
  171. s.Start()
  172. resp, err := client.ListUserProjects(ctx)
  173. s.Stop()
  174. if err != nil {
  175. return err
  176. }
  177. var projID uint64
  178. if len(*resp) > 1 {
  179. // only give the option to select when more than one option exists
  180. projName, err := utils.PromptSelect("Select a project with ID", func() []string {
  181. var names []string
  182. for _, proj := range *resp {
  183. names = append(names, fmt.Sprintf("%s - %d", proj.Name, proj.ID))
  184. }
  185. return names
  186. }())
  187. if err != nil {
  188. return err
  189. }
  190. projID, _ = strconv.ParseUint(strings.Split(projName, " - ")[1], 10, 64)
  191. } else {
  192. projID = uint64((*resp)[0].ID)
  193. }
  194. err = cliConf.SetProject(ctx, client, uint(projID))
  195. if err != nil {
  196. return err
  197. }
  198. return nil
  199. }
  200. func listAndSetCluster(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConf config.CLIConfig, featureFlags config.FeatureFlags, cmd *cobra.Command, args []string) error {
  201. s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
  202. _ = s.Color("cyan")
  203. s.Suffix = " Loading list of clusters"
  204. s.Start()
  205. resp, err := client.ListProjectClusters(ctx, cliConf.Project)
  206. s.Stop()
  207. if err != nil {
  208. return err
  209. }
  210. var clusterID uint64
  211. if len(*resp) > 1 {
  212. clusterName, err := utils.PromptSelect("Select a cluster with ID", func() []string {
  213. var names []string
  214. for _, cluster := range *resp {
  215. names = append(names, fmt.Sprintf("%s - %d", cluster.Name, cluster.ID))
  216. }
  217. return names
  218. }())
  219. if err != nil {
  220. return err
  221. }
  222. clusterID, _ = strconv.ParseUint(strings.Split(clusterName, " - ")[1], 10, 64)
  223. } else {
  224. clusterID = uint64((*resp)[0].ID)
  225. }
  226. err = cliConf.SetCluster(uint(clusterID))
  227. if err != nil {
  228. return fmt.Errorf("unable to set cluster: %w", err)
  229. }
  230. return nil
  231. }
  232. func listAndSetRegistry(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConf config.CLIConfig, featureFlags config.FeatureFlags, cmd *cobra.Command, args []string) error {
  233. s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
  234. _ = s.Color("cyan")
  235. s.Suffix = " Loading list of registries"
  236. s.Start()
  237. resp, err := client.ListRegistries(ctx, cliConf.Project)
  238. s.Stop()
  239. if err != nil {
  240. return err
  241. }
  242. var regID uint64
  243. if len(*resp) > 1 {
  244. regName, err := utils.PromptSelect("Select a registry with ID", func() []string {
  245. var names []string
  246. for _, cluster := range *resp {
  247. names = append(names, fmt.Sprintf("%s - %d", cluster.Name, cluster.ID))
  248. }
  249. return names
  250. }())
  251. if err != nil {
  252. return err
  253. }
  254. regID, _ = strconv.ParseUint(strings.Split(regName, " - ")[1], 10, 64)
  255. } else {
  256. regID = uint64((*resp)[0].ID)
  257. }
  258. err = cliConf.SetRegistry(uint(regID))
  259. if err != nil {
  260. return fmt.Errorf("error setting registry: %w", err)
  261. }
  262. return nil
  263. }