config.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. package cmd
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "path/filepath"
  6. "github.com/fatih/color"
  7. "github.com/spf13/viper"
  8. flag "github.com/spf13/pflag"
  9. )
  10. // shared sets of flags used by multiple commands
  11. var driverFlagSet = flag.NewFlagSet("driver", flag.ExitOnError)
  12. var defaultFlagSet = flag.NewFlagSet("shared", flag.ExitOnError) // used by all commands
  13. var registryFlagSet = flag.NewFlagSet("registry", flag.ExitOnError)
  14. var helmRepoFlagSet = flag.NewFlagSet("helmrepo", flag.ExitOnError)
  15. // config is a shared object used by all commands
  16. var config = &CLIConfig{}
  17. // CLIConfig is the set of shared configuration options for the CLI commands.
  18. // This config is used by viper: calling Set() function for any parameter will
  19. // update the corresponding field in the viper config file.
  20. type CLIConfig struct {
  21. // Driver can be either "docker" or "local", and represents which driver is
  22. // used to run an instance of the server.
  23. Driver string `yaml:"driver"`
  24. Host string `yaml:"host"`
  25. Project uint `yaml:"project"`
  26. Cluster uint `yaml:"cluster"`
  27. Token string `yaml:"token"`
  28. Registry uint `yaml:"registry"`
  29. HelmRepo uint `yaml:"helm_repo"`
  30. }
  31. // InitAndLoadConfig populates the config object with the following precedence rules:
  32. // 1. flag
  33. // 2. env
  34. // 3. config
  35. // 4. default
  36. //
  37. // It populates the shared config object above
  38. func InitAndLoadConfig() {
  39. initFlagSet()
  40. // check that the .porter folder exists; create if not
  41. porterDir := filepath.Join(home, ".porter")
  42. if _, err := os.Stat(porterDir); os.IsNotExist(err) {
  43. os.Mkdir(porterDir, 0700)
  44. } else if err != nil {
  45. color.New(color.FgRed).Printf("%v\n", err)
  46. os.Exit(1)
  47. }
  48. viper.SetConfigName("porter")
  49. viper.SetConfigType("yaml")
  50. viper.AddConfigPath(porterDir)
  51. // Bind the flagset initialized above
  52. viper.BindPFlags(driverFlagSet)
  53. viper.BindPFlags(defaultFlagSet)
  54. viper.BindPFlags(registryFlagSet)
  55. viper.BindPFlags(helmRepoFlagSet)
  56. // Bind the environment variables with prefix "PORTER_"
  57. viper.SetEnvPrefix("PORTER")
  58. viper.BindEnv("host")
  59. viper.BindEnv("project")
  60. viper.BindEnv("cluster")
  61. viper.BindEnv("token")
  62. err := viper.ReadInConfig()
  63. if err != nil {
  64. if _, ok := err.(viper.ConfigFileNotFoundError); ok {
  65. // create blank config file
  66. err := ioutil.WriteFile(filepath.Join(home, ".porter", "porter.yaml"), []byte{}, 0644)
  67. if err != nil {
  68. color.New(color.FgRed).Printf("%v\n", err)
  69. os.Exit(1)
  70. }
  71. } else {
  72. // Config file was found but another error was produced
  73. color.New(color.FgRed).Printf("%v\n", err)
  74. os.Exit(1)
  75. }
  76. }
  77. // unmarshal the config into the shared config struct
  78. viper.Unmarshal(config)
  79. }
  80. // initFlagSet initializes the shared flags used by multiple commands
  81. func initFlagSet() {
  82. driverFlagSet.StringVar(
  83. &config.Driver,
  84. "driver",
  85. "local",
  86. "driver to use (local or docker)",
  87. )
  88. defaultFlagSet.StringVar(
  89. &config.Host,
  90. "host",
  91. "https://dashboard.getporter.dev",
  92. "host URL of Porter instance",
  93. )
  94. defaultFlagSet.UintVar(
  95. &config.Project,
  96. "project",
  97. 0,
  98. "project ID of Porter project",
  99. )
  100. defaultFlagSet.UintVar(
  101. &config.Cluster,
  102. "cluster",
  103. 0,
  104. "cluster ID of Porter cluster",
  105. )
  106. defaultFlagSet.StringVar(
  107. &config.Token,
  108. "token",
  109. "",
  110. "token for Porter authentication",
  111. )
  112. registryFlagSet.UintVar(
  113. &config.Registry,
  114. "registry",
  115. 0,
  116. "registry ID of connected Porter registry",
  117. )
  118. helmRepoFlagSet.UintVar(
  119. &config.HelmRepo,
  120. "helmrepo",
  121. 0,
  122. "helm repo ID of connected Porter Helm repository",
  123. )
  124. }
  125. func (c *CLIConfig) SetDriver(driver string) error {
  126. viper.Set("driver", driver)
  127. color.New(color.FgGreen).Printf("Set the current driver as %s\n", driver)
  128. err := viper.WriteConfig()
  129. if err != nil {
  130. return err
  131. }
  132. config.Driver = driver
  133. return nil
  134. }
  135. func (c *CLIConfig) SetHost(host string) error {
  136. viper.Set("host", host)
  137. color.New(color.FgGreen).Printf("Set the current host as %s\n", host)
  138. err := viper.WriteConfig()
  139. if err != nil {
  140. return err
  141. }
  142. config.Host = host
  143. return nil
  144. }
  145. func (c *CLIConfig) SetProject(projectID uint) error {
  146. viper.Set("project", projectID)
  147. color.New(color.FgGreen).Printf("Set the current project as %d\n", projectID)
  148. err := viper.WriteConfig()
  149. if err != nil {
  150. return err
  151. }
  152. config.Project = projectID
  153. return nil
  154. }
  155. func (c *CLIConfig) SetCluster(clusterID uint) error {
  156. viper.Set("cluster", clusterID)
  157. color.New(color.FgGreen).Printf("Set the current cluster as %d\n", clusterID)
  158. err := viper.WriteConfig()
  159. if err != nil {
  160. return err
  161. }
  162. config.Cluster = clusterID
  163. return nil
  164. }
  165. func (c *CLIConfig) SetToken(token string) error {
  166. viper.Set("token", token)
  167. err := viper.WriteConfig()
  168. if err != nil {
  169. return err
  170. }
  171. config.Token = token
  172. return nil
  173. }
  174. func (c *CLIConfig) SetRegistry(registryID uint) error {
  175. viper.Set("registry", registryID)
  176. color.New(color.FgGreen).Printf("Set the current registry as %d\n", registryID)
  177. err := viper.WriteConfig()
  178. if err != nil {
  179. return err
  180. }
  181. config.Registry = registryID
  182. return nil
  183. }
  184. func (c *CLIConfig) SetHelmRepo(helmRepoID uint) error {
  185. viper.Set("helm_repo", helmRepoID)
  186. color.New(color.FgGreen).Printf("Set the current Helm repo as %d\n", helmRepoID)
  187. err := viper.WriteConfig()
  188. if err != nil {
  189. return err
  190. }
  191. config.HelmRepo = helmRepoID
  192. return nil
  193. }
  194. // var configCmd = &cobra.Command{
  195. // Use: "config",
  196. // Short: "Commands that control local configuration settings",
  197. // Run: func(cmd *cobra.Command, args []string) {
  198. // if err := printConfig(); err != nil {
  199. // color.New(color.FgRed).Printf("An error occurred: %v\n", err)
  200. // os.Exit(1)
  201. // }
  202. // },
  203. // }
  204. // var config.SetProjectCmd = &cobra.Command{
  205. // Use: "set-project [id]",
  206. // Args: cobra.ExactArgs(1),
  207. // Short: "Saves the project id in the default configuration",
  208. // Run: func(cmd *cobra.Command, args []string) {
  209. // projID, err := strconv.ParseUint(args[0], 10, 64)
  210. // if err != nil {
  211. // color.New(color.FgRed).Printf("An error occurred: %v\n", err)
  212. // os.Exit(1)
  213. // }
  214. // err = config.SetProject(uint(projID))
  215. // if err != nil {
  216. // color.New(color.FgRed).Printf("An error occurred: %v\n", err)
  217. // os.Exit(1)
  218. // }
  219. // },
  220. // }
  221. // var config.SetClusterCmd = &cobra.Command{
  222. // Use: "set-cluster [id]",
  223. // Args: cobra.ExactArgs(1),
  224. // Short: "Saves the cluster id in the default configuration",
  225. // Run: func(cmd *cobra.Command, args []string) {
  226. // clusterID, err := strconv.ParseUint(args[0], 10, 64)
  227. // if err != nil {
  228. // color.New(color.FgRed).Printf("An error occurred: %v\n", err)
  229. // os.Exit(1)
  230. // }
  231. // err = config.SetCluster(uint(clusterID))
  232. // if err != nil {
  233. // color.New(color.FgRed).Printf("An error occurred: %v\n", err)
  234. // os.Exit(1)
  235. // }
  236. // },
  237. // }
  238. // var setRegistryCmd = &cobra.Command{
  239. // Use: "set-registry [id]",
  240. // Args: cobra.ExactArgs(1),
  241. // Short: "Saves the registry id in the default configuration",
  242. // Run: func(cmd *cobra.Command, args []string) {
  243. // registryID, err := strconv.ParseUint(args[0], 10, 64)
  244. // if err != nil {
  245. // color.New(color.FgRed).Printf("An error occurred: %v\n", err)
  246. // os.Exit(1)
  247. // }
  248. // err = setRegistry(uint(registryID))
  249. // if err != nil {
  250. // color.New(color.FgRed).Printf("An error occurred: %v\n", err)
  251. // os.Exit(1)
  252. // }
  253. // },
  254. // }
  255. // var setHelmRepoCmd = &cobra.Command{
  256. // Use: "set-helmrepo [id]",
  257. // Args: cobra.ExactArgs(1),
  258. // Short: "Saves the helm repo id in the default configuration",
  259. // Run: func(cmd *cobra.Command, args []string) {
  260. // hrID, err := strconv.ParseUint(args[0], 10, 64)
  261. // if err != nil {
  262. // color.New(color.FgRed).Printf("An error occurred: %v\n", err)
  263. // os.Exit(1)
  264. // }
  265. // err = setHelmRepo(uint(hrID))
  266. // if err != nil {
  267. // color.New(color.FgRed).Printf("An error occurred: %v\n", err)
  268. // os.Exit(1)
  269. // }
  270. // },
  271. // }
  272. // var config.SetHostCmd = &cobra.Command{
  273. // Use: "set-host [host]",
  274. // Args: cobra.ExactArgs(1),
  275. // Short: "Saves the host in the default configuration",
  276. // Run: func(cmd *cobra.Command, args []string) {
  277. // err := config.SetHost(args[0])
  278. // if err != nil {
  279. // color.New(color.FgRed).Printf("An error occurred: %v\n", err)
  280. // os.Exit(1)
  281. // }
  282. // },
  283. // }
  284. // func init() {
  285. // rootCmd.AddCommand(configCmd)
  286. // configCmd.AddCommand(config.SetProjectCmd)
  287. // configCmd.AddCommand(config.SetClusterCmd)
  288. // configCmd.AddCommand(config.SetHostCmd)
  289. // configCmd.AddCommand(setRegistryCmd)
  290. // configCmd.AddCommand(setHelmRepoCmd)
  291. // }
  292. // func setDriver(driver string) error {
  293. // viper.Set("driver", driver)
  294. // err := viper.WriteConfig()
  295. // color.New(color.FgGreen).Printf("Set the current driver as %s\n", driver)
  296. // return err
  297. // }
  298. // func getDriver() string {
  299. // if driver != "" {
  300. // return driver
  301. // }
  302. // if opts.driver != "" {
  303. // return opts.driver
  304. // }
  305. // return viper.GetString("driver")
  306. // }
  307. // func printConfig() error {
  308. // config, err := ioutil.ReadFile(filepath.Join(home, ".porter", "porter.yaml"))
  309. // if err != nil {
  310. // return err
  311. // }
  312. // fmt.Printf(string(config))
  313. // return nil
  314. // }
  315. // func config.SetProject(id uint) error {
  316. // viper.Set("project", id)
  317. // color.New(color.FgGreen).Printf("Set the current project id as %d\n", id)
  318. // return viper.WriteConfig()
  319. // }
  320. // func config.SetCluster(id uint) error {
  321. // viper.Set("cluster", id)
  322. // color.New(color.FgGreen).Printf("Set the current cluster id as %d\n", id)
  323. // return viper.WriteConfig()
  324. // }
  325. // func setRegistry(id uint) error {
  326. // viper.Set("registry", id)
  327. // color.New(color.FgGreen).Printf("Set the current registry id as %d\n", id)
  328. // return viper.WriteConfig()
  329. // }
  330. // func setHelmRepo(id uint) error {
  331. // viper.Set("helm_repo", id)
  332. // color.New(color.FgGreen).Printf("Set the current helm repo id as %d\n", id)
  333. // return viper.WriteConfig()
  334. // }
  335. // func config.SetHost(host string) error {
  336. // viper.Set("host", host)
  337. // err := viper.WriteConfig()
  338. // color.New(color.FgGreen).Printf("Set the current host as %s\n", host)
  339. // return err
  340. // }
  341. // func config.SetToken(token string) error {
  342. // viper.Set("token", token)
  343. // err := viper.WriteConfig()
  344. // return err
  345. // }
  346. // func config.Host string {
  347. // if host != "" {
  348. // return host
  349. // }
  350. // return viper.GetString("host")
  351. // }
  352. // func config.Token string {
  353. // return viper.GetString("token")
  354. // }
  355. // func config.Cluster() uint {
  356. // if clusterID != 0 {
  357. // return clusterID
  358. // }
  359. // return viper.GetUint("cluster")
  360. // }
  361. // func config.Registry uint {
  362. // if registryID != 0 {
  363. // return registryID
  364. // }
  365. // return viper.GetUint("registry")
  366. // }
  367. // func config.HelmRepo() uint {
  368. // if helmRepoID != 0 {
  369. // return helmRepoID
  370. // }
  371. // return viper.GetUint("helm_repo")
  372. // }
  373. // func config.Project uint {
  374. // if projectID != 0 {
  375. // return projectID
  376. // }
  377. // return viper.GetUint("project")
  378. // }