config.go 9.1 KB

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