From d37f1b291fc5816013bbde31673fbb8195dd304b Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Fri, 19 Jul 2024 08:59:54 +1000 Subject: [PATCH] feat: introduce new configuration management --- cmd/add.go | 4 +- cmd/config.go | 404 --------- cmd/config_test.go | 74 -- cmd/configuration.go | 780 ++++++++++++++++++ cmd/delete.go | 4 +- cmd/deploy.go | 48 +- cmd/deploytarget.go | 51 +- cmd/deploytargetconfig.go | 44 +- cmd/environment.go | 42 +- cmd/get.go | 53 +- cmd/groups.go | 70 +- cmd/import.go | 29 +- cmd/list.go | 179 ++-- cmd/login.go | 64 +- cmd/logs.go | 24 +- cmd/notificationsemail.go | 78 +- cmd/notificationsrocketchat.go | 78 +- cmd/notificationsslack.go | 79 +- cmd/notificationsteams.go | 78 +- cmd/notificationswebhook.go | 78 +- cmd/organization.go | 33 +- cmd/project.go | 76 +- cmd/raw.go | 9 +- cmd/retrieve.go | 13 +- cmd/root.go | 271 +++--- cmd/run.go | 2 +- cmd/shared.go | 9 - cmd/ssh.go | 19 +- cmd/tasks.go | 90 +- cmd/update.go | 4 +- cmd/upload.go | 2 +- cmd/users.go | 96 +-- cmd/variables.go | 18 +- cmd/web.go | 55 -- cmd/whoami.go | 11 +- docs/commands/lagoon.md | 4 +- .../commands/lagoon_add_project-rocketchat.md | 41 - docs/commands/lagoon_add_project-slack.md | 41 - docs/commands/lagoon_add_restore.md | 42 - docs/commands/lagoon_add_rocketchat.md | 44 - docs/commands/lagoon_add_slack.md | 44 - docs/commands/lagoon_add_variable.md | 43 - docs/commands/lagoon_config.md | 41 - docs/commands/lagoon_config_add.md | 46 -- docs/commands/lagoon_config_list.md | 39 - docs/commands/lagoon_configuration.md | 44 + .../lagoon_configuration_add-context.md | 46 ++ .../commands/lagoon_configuration_add-user.md | 39 + ...md => lagoon_configuration_config-path.md} | 10 +- .../lagoon_configuration_convert-config.md | 46 ++ ...> lagoon_configuration_default-context.md} | 11 +- ...ure.md => lagoon_configuration_feature.md} | 15 +- ... => lagoon_configuration_list-contexts.md} | 10 +- ....md => lagoon_configuration_list-users.md} | 10 +- .../lagoon_configuration_update-context.md | 46 ++ .../lagoon_configuration_update-user.md | 39 + .../lagoon_delete_project-by-metadata.md | 40 - docs/commands/lagoon_delete_project-email.md | 40 - .../lagoon_delete_project-microsoftteams.md | 40 - .../lagoon_delete_project-rocketchat.md | 40 - docs/commands/lagoon_delete_project-slack.md | 40 - .../commands/lagoon_delete_project-webhook.md | 40 - docs/commands/lagoon_delete_rocketchat.md | 40 - docs/commands/lagoon_delete_slack.md | 40 - .../lagoon_get_project-by-metadata.md | 41 - docs/commands/lagoon_kibana.md | 38 - .../lagoon_list_project-by-metadata.md | 41 - docs/commands/lagoon_list_rocketchat.md | 39 - docs/commands/lagoon_list_slack.md | 39 - docs/commands/lagoon_list_users.md | 40 - .../lagoon_update_project-by-metadata.md | 41 - docs/commands/lagoon_update_rocketchat.md | 44 - docs/commands/lagoon_update_slack.md | 44 - docs/commands/lagoon_web.md | 38 - docs/config.md | 150 ++-- go.mod | 7 +- go.sum | 24 +- internal/lagoon/config.go | 15 + 78 files changed, 1910 insertions(+), 2681 deletions(-) delete mode 100644 cmd/config.go delete mode 100644 cmd/config_test.go create mode 100644 cmd/configuration.go delete mode 100644 cmd/web.go delete mode 100644 docs/commands/lagoon_add_project-rocketchat.md delete mode 100644 docs/commands/lagoon_add_project-slack.md delete mode 100644 docs/commands/lagoon_add_restore.md delete mode 100644 docs/commands/lagoon_add_rocketchat.md delete mode 100644 docs/commands/lagoon_add_slack.md delete mode 100644 docs/commands/lagoon_add_variable.md delete mode 100644 docs/commands/lagoon_config.md delete mode 100644 docs/commands/lagoon_config_add.md delete mode 100644 docs/commands/lagoon_config_list.md create mode 100644 docs/commands/lagoon_configuration.md create mode 100644 docs/commands/lagoon_configuration_add-context.md create mode 100644 docs/commands/lagoon_configuration_add-user.md rename docs/commands/{lagoon_config_current.md => lagoon_configuration_config-path.md} (81%) create mode 100644 docs/commands/lagoon_configuration_convert-config.md rename docs/commands/{lagoon_config_default.md => lagoon_configuration_default-context.md} (77%) rename docs/commands/{lagoon_config_feature.md => lagoon_configuration_feature.md} (66%) rename docs/commands/{lagoon_config_delete.md => lagoon_configuration_list-contexts.md} (81%) rename docs/commands/{lagoon_config_lagoon-version.md => lagoon_configuration_list-users.md} (81%) create mode 100644 docs/commands/lagoon_configuration_update-context.md create mode 100644 docs/commands/lagoon_configuration_update-user.md delete mode 100644 docs/commands/lagoon_delete_project-by-metadata.md delete mode 100644 docs/commands/lagoon_delete_project-email.md delete mode 100644 docs/commands/lagoon_delete_project-microsoftteams.md delete mode 100644 docs/commands/lagoon_delete_project-rocketchat.md delete mode 100644 docs/commands/lagoon_delete_project-slack.md delete mode 100644 docs/commands/lagoon_delete_project-webhook.md delete mode 100644 docs/commands/lagoon_delete_rocketchat.md delete mode 100644 docs/commands/lagoon_delete_slack.md delete mode 100644 docs/commands/lagoon_get_project-by-metadata.md delete mode 100644 docs/commands/lagoon_kibana.md delete mode 100644 docs/commands/lagoon_list_project-by-metadata.md delete mode 100644 docs/commands/lagoon_list_rocketchat.md delete mode 100644 docs/commands/lagoon_list_slack.md delete mode 100644 docs/commands/lagoon_list_users.md delete mode 100644 docs/commands/lagoon_update_project-by-metadata.md delete mode 100644 docs/commands/lagoon_update_rocketchat.md delete mode 100644 docs/commands/lagoon_update_slack.md delete mode 100644 docs/commands/lagoon_web.md diff --git a/cmd/add.go b/cmd/add.go index fd74a218..4d0172a0 100644 --- a/cmd/add.go +++ b/cmd/add.go @@ -9,7 +9,7 @@ var addCmd = &cobra.Command{ Aliases: []string{"a"}, Short: "Add a project, or add notifications and variables to projects or environments", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } @@ -18,7 +18,7 @@ var addNotificationCmd = &cobra.Command{ Aliases: []string{"n"}, Short: "Add notifications or add notifications to projects", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } diff --git a/cmd/config.go b/cmd/config.go deleted file mode 100644 index 75fb4660..00000000 --- a/cmd/config.go +++ /dev/null @@ -1,404 +0,0 @@ -package cmd - -import ( - "context" - "encoding/json" - "fmt" - "os" - "path/filepath" - "sort" - "strings" - - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/internal/lagoon/client" - "github.com/uselagoon/lagoon-cli/pkg/output" - "gopkg.in/yaml.v3" -) - -// LagoonConfigFlags . -type LagoonConfigFlags struct { - Lagoon string `json:"lagoon,omitempty"` - Hostname string `json:"hostname,omitempty"` - Port string `json:"port,omitempty"` - GraphQL string `json:"graphql,omitempty"` - Token string `json:"token,omitempty"` - UI string `json:"ui,omitempty"` - Kibana string `json:"kibana,omitempty"` - SSHKey string `json:"sshkey,omitempty"` - SSHPortal bool `json:"sshportal,omitempty"` -} - -func parseLagoonConfig(flags pflag.FlagSet) LagoonConfigFlags { - configMap := make(map[string]interface{}) - flags.VisitAll(func(f *pflag.Flag) { - if flags.Changed(f.Name) { - configMap[f.Name] = f.Value - } - }) - jsonStr, _ := json.Marshal(configMap) - parsedFlags := LagoonConfigFlags{} - json.Unmarshal(jsonStr, &parsedFlags) - return parsedFlags -} - -var configCmd = &cobra.Command{ - Use: "config", - Aliases: []string{"c"}, - Short: "Configure Lagoon CLI", - PersistentPreRun: func(cmd *cobra.Command, args []string) { - }, -} - -var configDefaultCmd = &cobra.Command{ - Use: "default", - Aliases: []string{"d"}, - Short: "Set the default Lagoon to use", - Run: func(cmd *cobra.Command, args []string) { - lagoonConfig := parseLagoonConfig(*cmd.Flags()) - if lagoonConfig.Lagoon == "" { - fmt.Println("Not enough arguments") - cmd.Help() - os.Exit(1) - } - lagoonCLIConfig.Default = strings.TrimSpace(string(lagoonConfig.Lagoon)) - contextExists := false - for l := range lagoonCLIConfig.Lagoons { - if l == lagoonCLIConfig.Current { - contextExists = true - } - } - if !contextExists { - fmt.Println(fmt.Printf("Chosen context '%s' doesn't exist in config file", lagoonCLIConfig.Current)) - os.Exit(1) - } - err := writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)) - handleError(err) - - resultData := output.Result{ - Result: "success", - ResultData: map[string]interface{}{ - "default-lagoon": lagoonConfig.Lagoon, - }, - } - output.RenderResult(resultData, outputOptions) - }, -} - -var configLagoonsCmd = &cobra.Command{ - Use: "list", - Aliases: []string{"l"}, - Short: "View all configured Lagoon instances", - RunE: func(cmd *cobra.Command, args []string) error { - var data []output.Data - for l, lc := range lagoonCLIConfig.Lagoons { - var isDefault, isCurrent string - if l == lagoonCLIConfig.Default { - isDefault = "(default)" - } - if l == lagoonCLIConfig.Current { - isCurrent = "(current)" - } - mapData := []string{ - returnNonEmptyString(fmt.Sprintf("%s%s%s", l, isDefault, isCurrent)), - returnNonEmptyString(lc.Version), - returnNonEmptyString(lc.GraphQL), - returnNonEmptyString(lc.HostName), - returnNonEmptyString(lc.Port), - } - if fullConfigList { - mapData = append(mapData, returnNonEmptyString(lc.UI)) - mapData = append(mapData, returnNonEmptyString(lc.Kibana)) - } - mapData = append(mapData, returnNonEmptyString(lc.SSHKey)) - data = append(data, mapData) - } - sort.Slice(data, func(i, j int) bool { - return data[i][0] < data[j][0] - }) - tableHeader := []string{ - "Name", - "Version", - "GraphQL", - "SSH-Hostname", - "SSH-Port", - } - if fullConfigList { - tableHeader = append(tableHeader, "UI-URL") - tableHeader = append(tableHeader, "Kibana-URL") - } - tableHeader = append(tableHeader, "SSH-Key") - output.RenderOutput(output.Table{ - Header: tableHeader, - Data: data, - }, outputOptions) - return nil - }, -} - -var configAddCmd = &cobra.Command{ - Use: "add", - Aliases: []string{"a"}, - Short: "Add information about an additional Lagoon instance to use", - RunE: func(cmd *cobra.Command, args []string) error { - lagoonConfig := parseLagoonConfig(*cmd.Flags()) - if lagoonConfig.Lagoon == "" { - return fmt.Errorf("missing arguments: Lagoon name is not defined") - } - - if lagoonConfig.Hostname != "" && lagoonConfig.Port != "" && lagoonConfig.GraphQL != "" { - lc := lagoonCLIConfig.Lagoons[lagoonConfig.Lagoon] - lc.HostName = lagoonConfig.Hostname - lc.Port = lagoonConfig.Port - lc.GraphQL = lagoonConfig.GraphQL - if lagoonConfig.UI != "" { - lc.UI = lagoonConfig.UI - } - if lagoonConfig.Kibana != "" { - lc.Kibana = lagoonConfig.Kibana - } - if lagoonConfig.Token != "" { - lc.Token = lagoonConfig.Token - } - if lagoonConfig.SSHKey != "" { - lc.SSHKey = lagoonConfig.SSHKey - } - // check identity files flag - identityFiles, err := cmd.Flags().GetStringSlice("publickey-identityfile") - if err != nil { - return err - } - if identityFiles != nil { - lc.PublicKeyIdentities = identityFiles - } - lagoonCLIConfig.Lagoons[lagoonConfig.Lagoon] = lc - if err := writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)); err != nil { - return fmt.Errorf("couldn't write config: %v", err) - } - output.RenderOutput(output.Table{ - Header: []string{ - "Name", - "GraphQL", - "SSH-Hostname", - "SSH-Port", - "UI-URL", - "Kibana-URL", - "SSH-Key", - }, - Data: []output.Data{ - []string{ - lagoonConfig.Lagoon, - lagoonConfig.GraphQL, - lagoonConfig.Hostname, - lagoonConfig.Port, - lagoonConfig.UI, - lagoonConfig.Kibana, - lagoonConfig.SSHKey, - }, - }, - }, outputOptions) - } else { - return fmt.Errorf("must have Hostname, Port, and GraphQL endpoint") - } - return nil - }, -} - -var configDeleteCmd = &cobra.Command{ - Use: "delete", - Aliases: []string{"d"}, - Short: "Delete a Lagoon instance configuration", - Run: func(cmd *cobra.Command, args []string) { - lagoonConfig := parseLagoonConfig(*cmd.Flags()) - - if lagoonConfig.Lagoon == "" { - fmt.Println("Missing arguments: Lagoon name is not defined") - cmd.Help() - os.Exit(1) - } - if yesNo(fmt.Sprintf("You are attempting to delete config for lagoon '%s', are you sure?", lagoonConfig.Lagoon)) { - err := removeConfig(lagoonConfig.Lagoon) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } - } - }, -} - -var configFeatureSwitch = &cobra.Command{ - Use: "feature", - Aliases: []string{"f"}, - Short: "Enable or disable CLI features", - Run: func(cmd *cobra.Command, args []string) { - switch updateCheck { - case "true": - lagoonCLIConfig.UpdateCheckDisable = true - case "false": - lagoonCLIConfig.UpdateCheckDisable = false - } - switch environmentFromDirectory { - case "true": - lagoonCLIConfig.EnvironmentFromDirectory = true - case "false": - lagoonCLIConfig.EnvironmentFromDirectory = false - } - if err := writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)); err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } - }, -} - -var configGetCurrent = &cobra.Command{ - Use: "current", - Aliases: []string{"cur"}, - Short: "Display the current Lagoon that commands would be executed against", - Run: func(cmd *cobra.Command, args []string) { - fmt.Println(lagoonCLIConfig.Current) - }, -} - -var configLagoonVersionCmd = &cobra.Command{ - Use: "lagoon-version", - Aliases: []string{"l"}, - Short: "Checks the current Lagoon for its version and sets it in the config file", - PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) - }, - RunE: func(cmd *cobra.Command, args []string) error { - debug, err := cmd.Flags().GetBool("debug") - if err != nil { - return err - } - current := lagoonCLIConfig.Current - lc := client.New( - lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, - lagoonCLIVersion, - debug) - lagoonVersion, err := lagoon.GetLagoonAPIVersion(context.TODO(), lc) - if err != nil { - return err - } - lagu := lagoonCLIConfig.Lagoons[current] - lagu.Version = lagoonVersion.LagoonVersion - lagoonCLIConfig.Lagoons[current] = lagu - if err = writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)); err != nil { - return fmt.Errorf("couldn't write config: %v", err) - } - fmt.Println(lagoonVersion.LagoonVersion) - return nil - }, -} - -var updateCheck string -var environmentFromDirectory string -var fullConfigList bool - -func init() { - configCmd.AddCommand(configAddCmd) - configCmd.AddCommand(configGetCurrent) - configCmd.AddCommand(configDefaultCmd) - configCmd.AddCommand(configDeleteCmd) - configCmd.AddCommand(configFeatureSwitch) - configCmd.AddCommand(configLagoonsCmd) - configCmd.AddCommand(configLagoonVersionCmd) - configAddCmd.Flags().StringVarP(&lagoonHostname, "hostname", "H", "", - "Lagoon SSH hostname") - configAddCmd.Flags().StringVarP(&lagoonPort, "port", "P", "", - "Lagoon SSH port") - configAddCmd.Flags().StringVarP(&lagoonGraphQL, "graphql", "g", "", - "Lagoon GraphQL endpoint") - configAddCmd.Flags().StringVarP(&lagoonToken, "token", "t", "", - "Lagoon GraphQL token") - configAddCmd.Flags().StringVarP(&lagoonUI, "ui", "u", "", - "Lagoon UI location (https://dashboard.amazeeio.cloud)") - configAddCmd.PersistentFlags().BoolVarP(&createConfig, "create-config", "", false, - "Create the config file if it is non existent (to be used with --config-file)") - configAddCmd.Flags().StringVarP(&lagoonKibana, "kibana", "k", "", - "Lagoon Kibana URL (https://logs.amazeeio.cloud)") - configAddCmd.Flags().StringVarP(&lagoonSSHKey, "ssh-key", "", "", - "SSH Key to use for this cluster for generating tokens") - configAddCmd.Flags().StringSliceP("publickey-identityfile", "", []string{}, - "Specific public key identity files to use when doing ssh-agent checks (support multiple)") - configLagoonsCmd.Flags().BoolVarP(&fullConfigList, "show-full", "", false, - "Show full config output when listing Lagoon configurations") - configFeatureSwitch.Flags().StringVarP(&updateCheck, "disable-update-check", "", "", - "Enable or disable checking of updates (true/false)") - configFeatureSwitch.Flags().StringVarP(&environmentFromDirectory, "enable-local-dir-check", "", "", - "Enable or disable checking of local directory for Lagoon project (true/false)") -} - -// readLagoonConfig reads the lagoon config from specified file. -func readLagoonConfig(lc *lagoon.Config, file string) error { - data, err := os.ReadFile(file) - if err != nil { - // if there is no file found in the specified location, prompt the user to create it with the default - // configuration to point to the amazeeio lagoon instance - if yesNo(fmt.Sprintf("Config file '%s' does not exist, do you want to create it with defaults?", file)) { - l := lagoon.Context{ - GraphQL: "https://api.lagoon.amazeeio.cloud/graphql", - HostName: "ssh.lagoon.amazeeio.cloud", - Token: "", - Port: "32222", - UI: "https://dashboard.amazeeio.cloud", - Kibana: "https://logs.amazeeio.cloud/", - } - lc.Lagoons = map[string]lagoon.Context{} - lc.Lagoons["amazeeio"] = l - lc.Default = "amazeeio" - return writeLagoonConfig(lc, file) - } - return err - } - err = yaml.Unmarshal(data, &lc) - if err != nil { - return fmt.Errorf("unable to unmarshal config, yaml is likely invalid: %v", err) - } - for ln, l := range lc.Lagoons { - if l.GraphQL == "" || l.HostName == "" || l.Port == "" { - return fmt.Errorf("configured lagoon %s is missing required configuration for graphql, hostname, or port", ln) - } - } - return nil - -} - -// functions to handle read/write of configuration file - -// writeLagoonConfig writes the lagoon config to specified file. -func writeLagoonConfig(lc *lagoon.Config, file string) error { - d, err := yaml.Marshal(&lc) - if err != nil { - return fmt.Errorf("unable to marshal config into valid yaml: %v", err) - } - err = os.WriteFile(file, d, 0777) - if err != nil { - return err - } - return nil -} - -func setConfigDefaultVersion(lc *lagoon.Config, lagoon string, version string) error { - if lc.Lagoons[lagoon].Version == "" { - l := lc.Lagoons[lagoon] - l.Version = version - lc.Lagoons[lagoon] = l - if err := writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)); err != nil { - return fmt.Errorf("couldn't write config: %v", err) - } - } - return nil -} - -func removeConfig(key string) error { - delete(lagoonCLIConfig.Lagoons, key) - if err := writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)); err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } - return nil -} diff --git a/cmd/config_test.go b/cmd/config_test.go deleted file mode 100644 index 0dbb7984..00000000 --- a/cmd/config_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package cmd - -import ( - "reflect" - "testing" - - "github.com/uselagoon/lagoon-cli/internal/lagoon" -) - -func TestConfigRead(t *testing.T) { - var testCases = map[string]struct { - input string - description string - readfailallowed bool - expect lagoon.Config - }{ - "valid-yaml": { - input: "testdata/lagoon.yml", - description: "This test checks that a valid and complete configuration is parsed", - readfailallowed: false, - expect: lagoon.Config{ - Current: "amazeeio", - Default: "amazeeio", - Lagoons: map[string]lagoon.Context{ - "amazeeio": { - GraphQL: "https://api.lagoon.amazeeio.cloud/graphql", - HostName: "ssh.lagoon.amazeeio.cloud", - Kibana: "https://logs-db-ui-lagoon-master.ch.amazee.io/", - UI: "https://ui-lagoon-master.ch.amazee.io", - Port: "32222", - }, - }, - UpdateCheckDisable: false, - EnvironmentFromDirectory: false, - }, - }, - "invalid-yaml": { - input: "testdata/lagoon.yml.invalid", - description: "This test checks to see if an invalid yaml config is not parsed", - readfailallowed: true, - expect: lagoon.Config{}, - }, - "missing-yaml": { - input: "testdata/lagoon.yml.missing", - description: "This test checks if a context is missing the required data (graphql, hostname, port)", - readfailallowed: true, - expect: lagoon.Config{ - Current: "amazeeio", - Default: "amazeeio", - Lagoons: map[string]lagoon.Context{ - "amazeeio": { - Kibana: "https://logs-db-ui-lagoon-master.ch.amazee.io/", - UI: "https://ui-lagoon-master.ch.amazee.io", - }, - }, - UpdateCheckDisable: false, - EnvironmentFromDirectory: false, - }, - }, - } - for name, tc := range testCases { - t.Run(name, func(tt *testing.T) { - lc := lagoon.Config{} - if err := readLagoonConfig(&lc, tc.input); err != nil { - if tc.readfailallowed == false { - tt.Fatal(err) - } - } - if !reflect.DeepEqual(lc, tc.expect) { - tt.Fatalf("Read config does not match expected config") - } - }) - } -} diff --git a/cmd/configuration.go b/cmd/configuration.go new file mode 100644 index 00000000..b915b89c --- /dev/null +++ b/cmd/configuration.go @@ -0,0 +1,780 @@ +package cmd + +import ( + "fmt" + "os" + "path/filepath" + "slices" + "strconv" + "strings" + + "github.com/manifoldco/promptui" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "github.com/uselagoon/lagoon-cli/internal/lagoon" + "github.com/uselagoon/lagoon-cli/pkg/output" + config "github.com/uselagoon/machinery/utils/config" + "golang.org/x/oauth2" + "gopkg.in/yaml.v3" +) + +var configCmd = &cobra.Command{ + Use: "configuration", + Aliases: []string{"config", "conf", "c"}, + Short: "Manage or view the contexts and users for interacting with Lagoon", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + }, +} + +var configListUsersCmd = &cobra.Command{ + Use: "list-users", + Aliases: []string{"lu"}, + Short: "View all configured Lagoon context users", + RunE: func(cmd *cobra.Command, args []string) error { + data := []output.Data{} + for _, user := range lConfig.Users { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%v", user.Name)), + returnNonEmptyString(fmt.Sprintf("%v", user.UserConfig.SSHKey)), + }) + } + output.RenderOutput(output.Table{ + Header: []string{ + "Name", + "SSH-Key", + }, + Data: data, + }, outputOptions) + return nil + }, +} + +var configListContextsCmd = &cobra.Command{ + Use: "list-contexts", + Aliases: []string{"lc"}, + Short: "View all configured Lagoon contexts", + RunE: func(cmd *cobra.Command, args []string) error { + data := []output.Data{} + featurePrefix := fmt.Sprintf("%s-", configFeaturePrefix) + for _, con := range lConfig.Contexts { + defa := false + if con.Name == lConfig.DefaultContext { + defa = true + } + selected := "" + if con.Name == cmdLagoon { + selected = "(selected)" + } + contextFeatures := map[string]bool{} + for f, b := range con.ContextConfig.Features { + // only add cli prefixed features in the cli + if strings.Contains(f, featurePrefix) { + // could include if it is context or global sourced here + contextFeatures[strings.TrimPrefix(f, featurePrefix)] = b + } + } + for f, b := range lConfig.Features { + // only add cli prefixed features in the cli + if strings.Contains(f, featurePrefix) { + if _, ok := con.ContextConfig.Features[f]; !ok { + // could include if it is context or global sourced here + contextFeatures[strings.TrimPrefix(f, featurePrefix)] = b + } + } + } + features := []string{} + // transform the features into a string slice for printing + for f, b := range contextFeatures { + features = append(features, fmt.Sprintf("%s=%t", f, b)) + } + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%v%s", con.Name, selected)), + returnNonEmptyString(fmt.Sprintf("%v", defa)), + returnNonEmptyString(fmt.Sprintf("%v", con.User)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.APIHostname)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.TokenHost)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.TokenPort)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.AuthenticationEndpoint)), + returnNonEmptyString(fmt.Sprintf("%v", strings.Join(features, ","))), + }) + } + output.RenderOutput(output.Table{ + Header: []string{ + "Name", + "Default", + "User", + "API-Hostname", + "Token-Hostname", + "Token-Port", + "Authentication-Hostname", + "Features", + }, + Data: data, + }, outputOptions) + return nil + }, +} + +var configAddUserCmd = &cobra.Command{ + Use: "add-user", + Aliases: []string{"au"}, + Short: "Add a new Lagoon context user", + RunE: func(cmd *cobra.Command, args []string) error { + uName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + uSSHKey, err := cmd.Flags().GetString("ssh-key") + if err != nil { + return err + } + // create the requested user + uConfig := config.UserConfig{ + Name: uName, + Grant: &oauth2.Token{}, + } + // visit the flags and check for any defined flags to set + cmd.Flags().Visit(func(f *pflag.Flag) { + if f.Name == "ssh-key" { + uConfig.SSHKey = uSSHKey + } + }) + err = lConfig.NewUser(uConfig) + if err != nil { + return err + } + data := []output.Data{} + for _, user := range lConfig.Users { + if user.Name == uName { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%v", user.Name)), + returnNonEmptyString(fmt.Sprintf("%v", user.UserConfig.SSHKey)), + }) + } + } + output.RenderOutput(output.Table{ + Header: []string{ + "Name", + "SSH-Key", + }, + Data: data, + }, outputOptions) + // then save it + return lConfig.WriteConfig() + }, +} + +var configUpdateUserCmd = &cobra.Command{ + Use: "update-user", + Aliases: []string{"uu"}, + Short: "Update a Lagoon context user", + RunE: func(cmd *cobra.Command, args []string) error { + uName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + uSSHKey, err := cmd.Flags().GetString("ssh-key") + if err != nil { + return err + } + // get the requested user + u, err := lConfig.GetUser(uName) + if err != nil { + return err + } + // visit the flags and check for any defined flags to set + cmd.Flags().Visit(func(f *pflag.Flag) { + if f.Name == "ssh-key" { + u.UserConfig.SSHKey = uSSHKey + } + }) + err = lConfig.UpdateUser(u.UserConfig) + if err != nil { + return err + } + data := []output.Data{} + for _, user := range lConfig.Users { + if user.Name == uName { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%v", user.Name)), + returnNonEmptyString(fmt.Sprintf("%v", user.UserConfig.SSHKey)), + }) + } + } + output.RenderOutput(output.Table{ + Header: []string{ + "Name", + "SSH-Key", + }, + Data: data, + }, outputOptions) + // then save it + return lConfig.WriteConfig() + }, +} + +var configAddContextCmd = &cobra.Command{ + Use: "add-context", + Aliases: []string{"ac"}, + Short: "Add a new Lagoon context", + RunE: func(cmd *cobra.Command, args []string) error { + cName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + cUser, err := cmd.Flags().GetString("user") + if err != nil { + return err + } + cAPIHost, err := cmd.Flags().GetString("api-hostname") + if err != nil { + return err + } + cTokenHost, err := cmd.Flags().GetString("token-hostname") + if err != nil { + return err + } + cTokenPort, err := cmd.Flags().GetInt("token-port") + if err != nil { + return err + } + cAuthHost, err := cmd.Flags().GetString("authentication-hostname") + if err != nil { + return err + } + cUIHost, err := cmd.Flags().GetString("ui-hostname") + if err != nil { + return err + } + cWebhookHost, err := cmd.Flags().GetString("webhook-hostname") + if err != nil { + return err + } + // create the requested context + cConfig := config.ContextConfig{ + Name: cName, + } + // visit the flags and check for any defined flags to set + cmd.Flags().Visit(func(f *pflag.Flag) { + if f.Name == "api-hostname" { + // strip /graphql from the host + cConfig.APIHostname = strings.TrimSuffix(cAPIHost, "/graphql") + } + if f.Name == "token-hostname" { + cConfig.TokenHost = cTokenHost + } + if f.Name == "token-port" { + cConfig.TokenPort = cTokenPort + } + if f.Name == "authentication-hostname" { + cConfig.AuthenticationEndpoint = cAuthHost + } + if f.Name == "ui-hostname" { + cConfig.UIHostname = cUIHost + } + if f.Name == "webhook-hostname" { + cConfig.WebhookEndpoint = cWebhookHost + } + }) + err = lConfig.NewContext(cConfig, cUser) + if err != nil { + return err + } + data := []output.Data{} + for _, con := range lConfig.Contexts { + defa := false + if con.Name == lConfig.DefaultContext { + defa = true + } + if con.Name == cName { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%v", con.Name)), + returnNonEmptyString(fmt.Sprintf("%v", defa)), + returnNonEmptyString(fmt.Sprintf("%v", con.User)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.APIHostname)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.TokenHost)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.TokenPort)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.AuthenticationEndpoint)), + }) + } + } + output.RenderOutput(output.Table{ + Header: []string{ + "Name", + "Default", + "User", + "API-Hostname", + "Token-Hostname", + "Token-Port", + "Authentication-Hostname", + }, + Data: data, + }, outputOptions) + // then save it + return lConfig.WriteConfig() + }, +} + +var configUpdateContextCmd = &cobra.Command{ + Use: "update-context", + Aliases: []string{"uc"}, + Short: "Update a Lagoon context", + RunE: func(cmd *cobra.Command, args []string) error { + cName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + cUser, err := cmd.Flags().GetString("user") + if err != nil { + return err + } + cAPIHost, err := cmd.Flags().GetString("api-hostname") + if err != nil { + return err + } + cTokenHost, err := cmd.Flags().GetString("token-hostname") + if err != nil { + return err + } + cTokenPort, err := cmd.Flags().GetInt("token-port") + if err != nil { + return err + } + cAuthHost, err := cmd.Flags().GetString("authentication-hostname") + if err != nil { + return err + } + cUIHost, err := cmd.Flags().GetString("ui-hostname") + if err != nil { + return err + } + cWebhookHost, err := cmd.Flags().GetString("webhook-hostname") + if err != nil { + return err + } + // get the requested context + cConfig, err := lConfig.GetContext(cName) + if err != nil { + return err + } + // visit the flags and check for any defined flags to set + cmd.Flags().Visit(func(f *pflag.Flag) { + // these will override the context ones if they are defined, otherwise the existing + // fields will remain untouched + if f.Name == "api-hostname" { + cConfig.ContextConfig.APIHostname = cAPIHost + } + if f.Name == "token-hostname" { + cConfig.ContextConfig.TokenHost = cTokenHost + } + if f.Name == "token-port" { + cConfig.ContextConfig.TokenPort = cTokenPort + } + if f.Name == "authentication-hostname" { + cConfig.ContextConfig.AuthenticationEndpoint = cAuthHost + } + if f.Name == "ui-hostname" { + cConfig.ContextConfig.UIHostname = cUIHost + } + if f.Name == "webhook-hostname" { + cConfig.ContextConfig.WebhookEndpoint = cWebhookHost + } + if f.Name == "user" { + cConfig.User = cUser + } + }) + // update the context within the configuration + err = lConfig.UpdateContext(cConfig.ContextConfig, cConfig.User) + if err != nil { + return err + } + data := []output.Data{} + for _, con := range lConfig.Contexts { + defa := false + if con.Name == lConfig.DefaultContext { + defa = true + } + if con.Name == cName { + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%v", con.Name)), + returnNonEmptyString(fmt.Sprintf("%v", defa)), + returnNonEmptyString(fmt.Sprintf("%v", con.User)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.APIHostname)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.TokenHost)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.TokenPort)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.AuthenticationEndpoint)), + }) + } + } + output.RenderOutput(output.Table{ + Header: []string{ + "Name", + "Default", + "User", + "API-Hostname", + "Token-Hostname", + "Token-Port", + "Authentication-Hostname", + }, + Data: data, + }, outputOptions) + // then save it + return lConfig.WriteConfig() + }, +} + +var configGetConfigPathCmd = &cobra.Command{ + Use: "config-path", + Aliases: []string{"cp"}, + Short: "Get the path of where the config file lives", + RunE: func(cmd *cobra.Command, args []string) error { + c := config.Config{} + path, err := c.GetConfigLocation() + if err != nil { + return err + } + fmt.Println(path) + return nil + }, +} + +var configSetDefaultCmd = &cobra.Command{ + Use: "default-context", + Aliases: []string{"dc"}, + Short: "Change which context is the default", + RunE: func(cmd *cobra.Command, args []string) error { + cName, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + if err = lConfig.SetDefaultContext(cName); err != nil { + return err + } + data := []output.Data{} + for _, con := range lConfig.Contexts { + defa := false + if con.Name == lConfig.DefaultContext { + defa = true + } + selected := "" + if con.Name == cmdLagoon { + selected = " (selected)" + } + data = append(data, []string{ + returnNonEmptyString(fmt.Sprintf("%v%s", con.Name, selected)), + returnNonEmptyString(fmt.Sprintf("%v", defa)), + returnNonEmptyString(fmt.Sprintf("%v", con.User)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.APIHostname)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.TokenHost)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.TokenPort)), + returnNonEmptyString(fmt.Sprintf("%v", con.ContextConfig.AuthenticationEndpoint)), + }) + } + output.RenderOutput(output.Table{ + Header: []string{ + "Name", + "Default", + "User", + "API-Hostname", + "Token-Hostname", + "Token-Port", + "Authentication-Hostname", + }, + Data: data, + }, outputOptions) + return lConfig.WriteConfig() + }, +} + +var configConvertLegacyConfig = &cobra.Command{ + Use: "convert-config", + Aliases: []string{"convert"}, + Short: "Convert legacy .lagoon.yml config to the new configuration format", + Long: `Convert legacy .lagoon.yml config to the new configuration format. +This will prompt you to provide any required information if it is missing from your legacy configuration. +Running this command initially will run in dry-run mode, if you're happy with the result you can run it again +with the --write-config flag to save the new configuration.`, + RunE: func(cmd *cobra.Command, args []string) error { + writeConfig, err := cmd.Flags().GetBool("write-config") + if err != nil { + return err + } + return convertConfig(writeConfig) + }, +} + +var configSetFeatureStatus = &cobra.Command{ + Use: "feature", + Aliases: []string{"feat", "f"}, + Short: "Enable or disable a feature for all contexts or a specific context", + RunE: func(cmd *cobra.Command, args []string) error { + cContext, err := cmd.Flags().GetString("context") + if err != nil { + return err + } + cFeature, err := cmd.Flags().GetString("feature") + if err != nil { + return err + } + cFeatureState, err := cmd.Flags().GetBool("state") + if err != nil { + return err + } + contextFeature := false + cmd.Flags().Visit(func(f *pflag.Flag) { + if f.Name == "context" { + contextFeature = true + } + }) + if cFeature == "" { + return fmt.Errorf("feature name must be provided") + } + if !slices.Contains(cliFeatures, cFeature) { + return fmt.Errorf("feature %s is not one of the supported features: %s", cFeature, cliFeatures) + } + if cContext != "" && contextFeature { + lConfig.SetContextFeature(cContext, configFeaturePrefix, cFeature, cFeatureState) + return lConfig.WriteConfig() + } else if cContext == "" && contextFeature { + return fmt.Errorf("context name must be provided") + } + lConfig.SetGlobalFeature(configFeaturePrefix, cFeature, cFeatureState) + return lConfig.WriteConfig() + }, +} + +func init() { + configCmd.AddCommand(configListContextsCmd) + configCmd.AddCommand(configListUsersCmd) + configCmd.AddCommand(configGetConfigPathCmd) + + configCmd.AddCommand(configConvertLegacyConfig) + configConvertLegacyConfig.Flags().Bool("write-config", false, "Whether the config should be written to the config file or not") + + configCmd.AddCommand(configSetDefaultCmd) + configSetDefaultCmd.Flags().String("name", "", "The name of the context to be default") + + configCmd.AddCommand(configAddContextCmd) + configAddContextCmd.Flags().String("name", "", "The name to reference this context as") + configAddContextCmd.Flags().String("api-hostname", "", "Lagoon API hostname (eg: https://api.lagoon.sh)") + configAddContextCmd.Flags().String("token-hostname", "", "Lagoon Token endpoint hostname (eg: token.lagoon.sh)") + configAddContextCmd.Flags().Int("token-port", 0, "Lagoon Token endpoint port (eg: 22)") + configAddContextCmd.Flags().String("authentication-hostname", "", "Lagoon authentication hostname (eg: https://keycloak.lagoon.sh)") + configAddContextCmd.Flags().String("user", "", "The user to associate to this context") + configAddContextCmd.Flags().String("ui-hostname", "", "Lagoon UI hostname (eg: https://ui.lagoon.sh)") + configAddContextCmd.Flags().String("webhook-hostname", "", "Lagoon webhook hostname (eg: https://webhook.lagoon.sh)") + + configCmd.AddCommand(configAddUserCmd) + configAddUserCmd.Flags().String("name", "", "The name to reference this user as") + configAddUserCmd.Flags().String("ssh-key", "", "The full path to this users ssh-key") + + configCmd.AddCommand(configUpdateUserCmd) + configUpdateUserCmd.Flags().String("name", "", "The name to reference this user as") + configUpdateUserCmd.Flags().String("ssh-key", "", "The full path to this users ssh-key") + + configCmd.AddCommand(configUpdateContextCmd) + configUpdateContextCmd.Flags().String("name", "", "The name to reference this context as") + configUpdateContextCmd.Flags().String("api-hostname", "", "Lagoon API hostname (eg: https://api.lagoon.sh)") + configUpdateContextCmd.Flags().String("token-hostname", "", "Lagoon Token endpoint hostname (eg: token.lagoon.sh)") + configUpdateContextCmd.Flags().Int("token-port", 0, "Lagoon Token endpoint port (eg: 22)") + configUpdateContextCmd.Flags().String("authentication-hostname", "", "Lagoon authentication hostname (eg: https://keycloak.lagoon.sh)") + configUpdateContextCmd.Flags().String("user", "", "The user to associate to this context") + configUpdateContextCmd.Flags().String("ui-hostname", "", "Lagoon UI hostname (eg: https://ui.lagoon.sh)") + configUpdateContextCmd.Flags().String("webhook-hostname", "", "Lagoon webhook hostname (eg: https://webhook.lagoon.sh)") + + configCmd.AddCommand(configSetFeatureStatus) + configSetFeatureStatus.Flags().Bool("state", false, "The state of the feature (--state=true or --state=false)") + configSetFeatureStatus.Flags().String("context", "", "If provided the feature will be enabled for this context, otherwise globally") + configSetFeatureStatus.Flags().String("feature", "", fmt.Sprintf("The name of the feature to enable or disable [%s]", strings.Join(cliFeatures, ","))) +} + +func getLegacyConfigFile(configPath *string, configName *string, configExtension *string, cmd *cobra.Command) error { + // check if we have an envvar or flag to define our confg file + var configFilePath string + configFilePath, err := cmd.Flags().GetString("config-file") + if err != nil { + return fmt.Errorf("error reading flag `config-file`: %v", err) + } + if configFilePath == "" { + if lagoonConfigEnvar, ok := os.LookupEnv("LAGOONCONFIG"); ok { + configFilePath = lagoonConfigEnvar + } + // prefer LAGOON_CONFIG_FILE + if lagoonConfigEnvar, ok := os.LookupEnv("LAGOON_CONFIG_FILE"); ok { + configFilePath = lagoonConfigEnvar + } + } + if configFilePath != "" { + if fileExists(configFilePath) || createConfig { + *configPath = filepath.Dir(configFilePath) + *configExtension = filepath.Ext(configFilePath) + *configName = strings.TrimSuffix(filepath.Base(configFilePath), *configExtension) + return nil + } + return fmt.Errorf("%s/%s File doesn't exist", *configPath, configFilePath) + } + // no config file found + return nil +} + +func readLegacyConfig() ([]byte, error) { + // check for the legacy config file + userPath, err := os.UserHomeDir() + if err != nil { + return nil, err + } + configFilePath = userPath + err = getLegacyConfigFile(&configFilePath, &configName, &configExtension, rootCmd) + if err != nil { + return nil, err + } + data, err := os.ReadFile(filepath.Join(configFilePath, configName+configExtension)) + if err != nil { + return nil, err + } + return data, nil +} + +func convertConfig(writeConfig bool) error { + data, err := readLegacyConfig() + if err != nil { + return err + } + lc := lagoon.Config{} + err = yaml.Unmarshal(data, &lc) + if err != nil { + return fmt.Errorf("unable to unmarshal config, yaml is likely invalid: %v", err) + } + + // convert the legacy config into the new user/context config file + cc := config.Config{} + for n, l := range lc.Lagoons { + // if l.KeycloakURL == "" { + // prompt for a keycloak url for the context if one does not exist + prompt := promptui.Prompt{ + Label: fmt.Sprintf("Enter authentication endpoint for context %s", n), + Default: "https://keycloak.example.com/auth", + AllowEdit: true, + } + result, err := prompt.Run() + if err != nil { + return err + } + // } + uConfig := config.UserConfig{ + Name: n, + Grant: &oauth2.Token{ + AccessToken: l.Token, + }, + SSHKey: l.SSHKey, + } + port, _ := strconv.Atoi(l.Port) + cConfig := config.ContextConfig{ + Name: n, + APIHostname: strings.TrimSuffix(l.GraphQL, "/graphql"), + TokenHost: l.HostName, + TokenPort: port, + AuthenticationEndpoint: result, + Version: l.Version, + UIHostname: l.UI, + } + err = cc.NewUser(uConfig) + if err != nil { + return err + } + err = cc.NewContext(cConfig, uConfig.Name) + if err != nil { + return err + } + } + cc.SetDefaultContext(lc.Default) + if writeConfig { + if err := cc.WriteConfig(); err != nil { + return err + } + } else { + cb, _ := yaml.Marshal(cc) + fmt.Println(string(cb)) + fmt.Println("configuration file not written, to save converted config run this again with the flag --write-config") + } + return nil +} + +// helper function for creating an initial configuration with prompts if no legacy or new config is detected +func createInitialConfig() error { + lConfig, _ = config.LoadConfig(true) + uPrompt := promptui.Prompt{ + Label: "Enter a user name", + Default: "user", + AllowEdit: true, + } + userName, err := uPrompt.Run() + if err != nil { + return fmt.Errorf("unable to create configuration: %s", err.Error()) + } + lConfig.NewUser(config.UserConfig{ + Name: userName, + }) + cPrompt := promptui.Prompt{ + Label: "Enter a context name", + Default: "lagoon", + AllowEdit: true, + } + cName, err := cPrompt.Run() + if err != nil { + return fmt.Errorf("unable to create configuration: %s", err.Error()) + } + prompt := promptui.Prompt{ + Label: "Enter API hostname, omit the /graphql path", + Default: "https://api.example.com", + AllowEdit: true, + } + apiHostname, err := prompt.Run() + if err != nil { + return fmt.Errorf("unable to create configuration: %s", err.Error()) + } + prompt2 := promptui.Prompt{ + Label: "Enter Authentication endpoint, this will likely be the keycloak service", + Default: "https://keycloak.example.com/auth", + AllowEdit: true, + } + authEndpoint, err := prompt2.Run() + if err != nil { + return fmt.Errorf("unable to create configuration: %s", err.Error()) + } + prompt3 := promptui.Prompt{ + Label: "Enter the SSH token endpoint to be used if SSH token generation is to be used", + Default: "token.example.com", + AllowEdit: true, + } + tokenHost, err := prompt3.Run() + if err != nil { + return fmt.Errorf("unable to create configuration: %s", err.Error()) + } + prompt4 := promptui.Prompt{ + Label: "Enter port for the SSH token endpoint", + Default: "22", + AllowEdit: true, + } + tokenPort, err := prompt4.Run() + if err != nil { + return fmt.Errorf("unable to create configuration: %s", err.Error()) + } + tP, err := strconv.Atoi(tokenPort) + if err != nil { + return fmt.Errorf("provided port is not a number: %s", err.Error()) + } + lConfig.NewContext(config.ContextConfig{ + Name: cName, + APIHostname: apiHostname, + AuthenticationEndpoint: authEndpoint, + TokenHost: tokenHost, + TokenPort: tP, + }, userName) + lConfig.SetDefaultContext(cName) + err = lConfig.WriteConfig() + if err != nil { + return fmt.Errorf("unable to create configuration: %s", err.Error()) + } + return nil +} diff --git a/cmd/delete.go b/cmd/delete.go index 85dea02b..620544be 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -9,7 +9,7 @@ var deleteCmd = &cobra.Command{ Aliases: []string{"del"}, Short: "Delete a project, or delete notifications and variables from projects or environments", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } @@ -18,7 +18,7 @@ var deleteNotificationCmd = &cobra.Command{ Aliases: []string{"n"}, Short: "Delete notifications or delete notifications from projects", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } diff --git a/cmd/deploy.go b/cmd/deploy.go index 8d038b8c..05985258 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -5,10 +5,9 @@ import ( "fmt" "strconv" - lclient "github.com/uselagoon/machinery/api/lagoon/client" - "github.com/spf13/cobra" "github.com/uselagoon/machinery/api/lagoon" + lclient "github.com/uselagoon/machinery/api/lagoon/client" "github.com/uselagoon/machinery/api/schema" ) @@ -26,7 +25,7 @@ This branch may or may not already exist in lagoon, if it already exists you may use 'lagoon deploy latest' instead`, Aliases: []string{"b"}, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -59,13 +58,12 @@ use 'lagoon deploy latest' instead`, } if yesNo(fmt.Sprintf("You are attempting to deploy branch '%s' for project '%s', are you sure?", branch, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) depBranch := &schema.DeployEnvironmentBranchInput{ Branch: branch, @@ -92,7 +90,7 @@ var deployPromoteCmd = &cobra.Command{ Short: "Promote an environment", Long: "Promote one environment to another", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -125,13 +123,12 @@ var deployPromoteCmd = &cobra.Command{ } if yesNo(fmt.Sprintf("You are attempting to promote environment '%s' to '%s' for project '%s', are you sure?", sourceEnvironment, destinationEnvironment, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.DeployPromote(context.TODO(), &schema.DeployEnvironmentPromoteInput{ SourceEnvironment: sourceEnvironment, @@ -157,7 +154,7 @@ var deployLatestCmd = &cobra.Command{ Long: `Deploy latest environment This environment should already exist in lagoon. It is analogous with the 'Deploy' button in the Lagoon UI`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { @@ -183,13 +180,12 @@ This environment should already exist in lagoon. It is analogous with the 'Deplo } if yesNo(fmt.Sprintf("You are attempting to deploy the latest environment '%s' for project '%s', are you sure?", cmdProjectEnvironment, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.DeployLatest(context.TODO(), &schema.DeployEnvironmentLatestInput{ Environment: schema.EnvironmentInput{ @@ -218,7 +214,7 @@ var deployPullrequestCmd = &cobra.Command{ Long: `Deploy a pullrequest This pullrequest may not already exist as an environment in lagoon.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -266,15 +262,13 @@ This pullrequest may not already exist as an environment in lagoon.`, return err } if yesNo(fmt.Sprintf("You are attempting to deploy pull request '%v' for project '%s', are you sure?", prNumber, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) - result, err := lagoon.DeployPullRequest(context.TODO(), &schema.DeployEnvironmentPullrequestInput{ Project: schema.ProjectInput{ Name: cmdProjectName, diff --git a/cmd/deploytarget.go b/cmd/deploytarget.go index 66bcc259..e8c8e97b 100644 --- a/cmd/deploytarget.go +++ b/cmd/deploytarget.go @@ -89,13 +89,13 @@ var addDeployTargetCmd = &cobra.Command{ if err != nil { return err } - current := lagoonCLIConfig.Current - lagoonToken := lagoonCLIConfig.Lagoons[current].Token + + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &lagoonToken, + lContext.ContextConfig.Version, + &utoken, debug) if yesNo(fmt.Sprintf("You are attempting to add '%s' DeployTarget, are you sure?", addDeployTarget.Name)) { @@ -207,13 +207,12 @@ var updateDeployTargetCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - lagoonToken := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &lagoonToken, + lContext.ContextConfig.Version, + &utoken, debug) updateDeployTarget := &schema.UpdateDeployTargetInput{ @@ -298,13 +297,12 @@ var deleteDeployTargetCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) deleteDeployTarget := &schema.DeleteDeployTargetInput{ @@ -330,7 +328,7 @@ var addDeployTargetToOrganizationCmd = &cobra.Command{ Aliases: []string{"org-dt"}, Short: "Add a deploy target to an Organization", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -349,13 +347,13 @@ var addDeployTargetToOrganizationCmd = &cobra.Command{ if err := requiredInputCheck("Organization name", organizationName, "Deploy Target", strconv.Itoa(int(deploytarget))); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) @@ -393,7 +391,7 @@ var removeDeployTargetFromOrganizationCmd = &cobra.Command{ Aliases: []string{"org-dt"}, Short: "Remove a deploy target from an Organization", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -413,13 +411,12 @@ var removeDeployTargetFromOrganizationCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) diff --git a/cmd/deploytargetconfig.go b/cmd/deploytargetconfig.go index cb4465f3..62cf6170 100644 --- a/cmd/deploytargetconfig.go +++ b/cmd/deploytargetconfig.go @@ -20,7 +20,7 @@ var addDeployTargetConfigCmd = &cobra.Command{ Hidden: false, Short: "Add deploytarget config to a project", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -48,13 +48,12 @@ var addDeployTargetConfigCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) @@ -114,7 +113,7 @@ var updateDeployTargetConfigCmd = &cobra.Command{ Hidden: false, Short: "Update a deploytarget config", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -145,13 +144,12 @@ var updateDeployTargetConfigCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) updateDeployTargetConfig := &schema.UpdateDeployTargetConfigInput{ @@ -208,7 +206,7 @@ var deleteDeployTargetConfigCmd = &cobra.Command{ Hidden: false, Short: "Delete a deploytarget config", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -223,13 +221,12 @@ var deleteDeployTargetConfigCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) @@ -259,7 +256,7 @@ var listDeployTargetConfigsCmd = &cobra.Command{ Hidden: false, Short: "List deploytarget configs for a project", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -271,13 +268,12 @@ var listDeployTargetConfigsCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) diff --git a/cmd/environment.go b/cmd/environment.go index 56aca2d6..4d8c5151 100644 --- a/cmd/environment.go +++ b/cmd/environment.go @@ -23,7 +23,7 @@ var deleteEnvCmd = &cobra.Command{ Aliases: []string{"e"}, Short: "Delete an environment", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -34,13 +34,12 @@ var deleteEnvCmd = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) if yesNo(fmt.Sprintf("You are attempting to delete environment '%s' from project '%s', are you sure?", cmdProjectEnvironment, cmdProjectName)) { environment, err := lagoon.DeleteEnvironment(context.TODO(), cmdProjectEnvironment, cmdProjectName, true, lc) @@ -61,7 +60,7 @@ var updateEnvironmentCmd = &cobra.Command{ Aliases: []string{"e"}, Short: "Update an environment", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -111,13 +110,12 @@ var updateEnvironmentCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if project.Name == "" { @@ -198,14 +196,12 @@ var listBackupsCmd = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { return err } - - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) @@ -268,14 +264,12 @@ This returns a direct URL to the backup, this is a signed download link with a l if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { return err } - - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) diff --git a/cmd/get.go b/cmd/get.go index 5d5ca03d..ecc72d45 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -25,7 +25,7 @@ var getCmd = &cobra.Command{ Aliases: []string{"g"}, Short: "Get info on a resource", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } @@ -34,7 +34,7 @@ var getProjectCmd = &cobra.Command{ Aliases: []string{"p"}, Short: "Get details about a project", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -48,13 +48,12 @@ var getProjectCmd = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetProjectByName(context.TODO(), cmdProjectName, lc) @@ -154,13 +153,12 @@ This returns information about a deployment, the logs of this build can also be return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) deployment, err := lagoon.GetDeploymentByName(context.TODO(), cmdProjectName, cmdProjectEnvironment, buildName, showLogs, lc) if err != nil { @@ -211,7 +209,7 @@ var getEnvironmentCmd = &cobra.Command{ Aliases: []string{"e"}, Short: "Get details about an environment", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -225,13 +223,12 @@ var getEnvironmentCmd = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetProjectByName(context.TODO(), cmdProjectName, lc) @@ -288,7 +285,7 @@ var getProjectKeyCmd = &cobra.Command{ Aliases: []string{"pk"}, Short: "Get a projects public key", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -299,13 +296,12 @@ var getProjectKeyCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) projectKey, err := lagoon.GetProjectKeyByName(context.TODO(), cmdProjectName, revealValue, lc) @@ -374,13 +370,12 @@ var getOrganizationCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) if err != nil { diff --git a/cmd/groups.go b/cmd/groups.go index b1ac7c39..7203aeb6 100644 --- a/cmd/groups.go +++ b/cmd/groups.go @@ -3,11 +3,13 @@ package cmd import ( "context" "fmt" - "slices" "strings" - "github.com/uselagoon/machinery/api/lagoon" + "slices" + lclient "github.com/uselagoon/machinery/api/lagoon/client" + + "github.com/uselagoon/machinery/api/lagoon" "github.com/uselagoon/machinery/api/schema" "github.com/spf13/cobra" @@ -21,7 +23,7 @@ var addGroupCmd = &cobra.Command{ Short: "Add a group to Lagoon, or add a group to an organization", Long: "To add a group to an organization, you'll need to include the `organization` flag and provide the name of the organization. You need to be an owner of this organization to do this.\nIf you're the organization owner and want to grant yourself ownership to this group to be able to deploy projects that may be added to it, specify the `owner` flag, otherwise you will still be able to add and remove users without being an owner", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -44,13 +46,12 @@ var addGroupCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) if organizationName != "" { @@ -99,7 +100,7 @@ var addUserToGroupCmd = &cobra.Command{ Aliases: []string{"ug"}, Short: "Add a user to a group in lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -140,13 +141,12 @@ var addUserToGroupCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) userGroupRole := &schema.UserGroupRoleInput{ @@ -172,7 +172,7 @@ var addProjectToGroupCmd = &cobra.Command{ Aliases: []string{"pg"}, Short: "Add a project to a group in lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -198,13 +198,12 @@ var addProjectToGroupCmd = &cobra.Command{ }, } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) @@ -234,7 +233,7 @@ var deleteUserFromGroupCmd = &cobra.Command{ Aliases: []string{"ug"}, Short: "Delete a user from a group in lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -259,13 +258,12 @@ var deleteUserFromGroupCmd = &cobra.Command{ GroupName: groupName, } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) if yesNo(fmt.Sprintf("You are attempting to delete user '%s' from group '%s', are you sure?", userEmail, groupName)) { @@ -291,7 +289,7 @@ var deleteProjectFromGroupCmd = &cobra.Command{ Aliases: []string{"pg"}, Short: "Delete a project from a group in lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -317,13 +315,12 @@ var deleteProjectFromGroupCmd = &cobra.Command{ }, } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) @@ -367,13 +364,12 @@ var deleteGroupCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) if yesNo(fmt.Sprintf("You are attempting to delete group '%s', are you sure?", groupName)) { diff --git a/cmd/import.go b/cmd/import.go index 3fda1329..dfeb4717 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -19,7 +19,7 @@ var importCmd = &cobra.Command{ By default this command will exit on encountering an error (such as an existing object). You can get it to continue anyway with --keep-going. To disable any prompts, use --force.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { importFile, err := cmd.Flags().GetString("import-file") @@ -39,21 +39,16 @@ You can get it to continue anyway with --keep-going. To disable any prompts, use return err } - current := lagoonCLIConfig.Current + current := lContext.Name if !yesNo(fmt.Sprintf( `Are you sure you want to import config from %s into "%s" lagoon?`, importFile, current)) { return nil // user cancelled } - - err = setConfigDefaultVersion(&lagoonCLIConfig, current, "1.0.0") - if err != nil { - return err - } lc := client.New( - lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), + lUser.UserConfig.Grant.AccessToken, + lContext.ContextConfig.Version, lagoonCLIVersion, debug) @@ -83,7 +78,7 @@ var exportCmd = &cobra.Command{ Long: `Export lagoon output to yaml You must specify to export a specific project by using the '-p ' flag`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { project, err := cmd.Flags().GetString("project") @@ -102,21 +97,17 @@ You must specify to export a specific project by using the '-p ' f return err } - current := lagoonCLIConfig.Current + current := lContext.Name if !yesNo(fmt.Sprintf( `Are you sure you want to export lagoon config for %s on "%s" lagoon?`, project, current)) { return nil // user cancelled } - err = setConfigDefaultVersion(&lagoonCLIConfig, current, "1.0.0") - if err != nil { - return err - } lc := client.New( - lagoonCLIConfig.Lagoons[current].GraphQL, - lagoonCLIConfig.Lagoons[current].Token, - lagoonCLIConfig.Lagoons[current].Version, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), + lUser.UserConfig.Grant.AccessToken, + lContext.ContextConfig.Version, lagoonCLIVersion, debug) diff --git a/cmd/list.go b/cmd/list.go index 9483e882..3b35ad25 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -23,7 +23,7 @@ var listCmd = &cobra.Command{ Use: "list", Short: "List projects, environments, deployments, variables or notifications", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } @@ -39,13 +39,12 @@ var listProjectsCmd = &cobra.Command{ if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) projects, err := lagoon.ListAllProjects(context.TODO(), lc) @@ -101,13 +100,12 @@ var listDeployTargetsCmd = &cobra.Command{ if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) deploytargets, err := lagoon.ListDeployTargets(context.TODO(), lc) if err != nil { @@ -166,13 +164,12 @@ var listGroupsCmd = &cobra.Command{ if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) groups, err := lagoon.ListAllGroups(context.TODO(), lc) @@ -226,13 +223,12 @@ var listGroupProjectsCmd = &cobra.Command{ } } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) var groupProjects *[]schema.Group @@ -289,7 +285,7 @@ var listEnvironmentsCmd = &cobra.Command{ Aliases: []string{"e"}, Short: "List environments for a project (alias: e)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -300,13 +296,12 @@ var listEnvironmentsCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) environments, err := lagoon.GetEnvironmentsByProjectName(context.TODO(), cmdProjectName, lc) if err != nil { @@ -363,13 +358,12 @@ var listVariablesCmd = &cobra.Command{ if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) in := &schema.EnvVariableByProjectEnvironmentNameInput{ Project: cmdProjectName, @@ -441,13 +435,12 @@ var listDeploymentsCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) @@ -503,13 +496,12 @@ var listTasksCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) @@ -569,13 +561,12 @@ Without a group name, this query may time out in large Lagoon instalschema.`, if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) data := []output.Data{} if groupName != "" { @@ -636,13 +627,12 @@ This query can take a long time to run if there are a lot of users.`, if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) allUsers, err := lagoon.AllUsers(context.TODO(), schema.AllUsersFilter{ Email: emailAddress, @@ -689,13 +679,12 @@ var listUsersGroupsCmd = &cobra.Command{ if err := requiredInputCheck("Email Address", emailAddress); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) allUsers, err := lagoon.GetUserByEmail(context.TODO(), emailAddress, lc) if err != nil { @@ -736,13 +725,12 @@ var listInvokableTasks = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) @@ -781,7 +769,7 @@ var listNotificationCmd = &cobra.Command{ Aliases: []string{"n"}, Short: "List all notifications or notifications on projects", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } @@ -790,7 +778,7 @@ var listProjectGroupsCmd = &cobra.Command{ Aliases: []string{"pg"}, Short: "List groups in a project (alias: pg)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -801,13 +789,12 @@ var listProjectGroupsCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) projectGroups, err := lagoon.GetProjectGroups(context.TODO(), cmdProjectName, lc) if err != nil { @@ -861,13 +848,12 @@ var listOrganizationProjectsCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) @@ -925,13 +911,12 @@ var listOrganizationGroupsCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) @@ -993,13 +978,12 @@ var listOrganizationDeployTargetsCmd = &cobra.Command{ return fmt.Errorf("missing arguments: Organization name or ID is not defined") } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) deployTargets, err := lagoon.ListDeployTargetsByOrganizationNameOrID(context.TODO(), nullStrCheck(organizationName), nullUintCheck(organizationID), lc) if err != nil { @@ -1052,13 +1036,12 @@ var ListOrganizationUsersCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) users, err := lagoon.UsersByOrganizationName(context.TODO(), organizationName, lc) if err != nil { @@ -1104,13 +1087,12 @@ var ListOrganizationAdminsCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) users, err := lagoon.ListOrganizationAdminsByName(context.TODO(), organizationName, lc) if err != nil { @@ -1153,13 +1135,12 @@ var listOrganizationsCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organizations, err := lagoon.AllOrganizations(context.TODO(), lc) diff --git a/cmd/login.go b/cmd/login.go index 158b1bdd..5d50718f 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -2,15 +2,16 @@ package cmd import ( "bytes" + "encoding/json" "fmt" "net" "os" - "path/filepath" - "strings" "github.com/spf13/cobra" + auth "github.com/uselagoon/machinery/utils/auth" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" + "golang.org/x/oauth2" terminal "golang.org/x/term" ) @@ -19,7 +20,7 @@ var loginCmd = &cobra.Command{ Short: "Log into a Lagoon instance", Aliases: []string{"l"}, Run: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid fmt.Println("Token fetched and saved.") }, } @@ -108,30 +109,37 @@ func publicKey(path, publicKeyOverride string, publicKeyIdentities []string, ski } func loginToken() error { - out, err := retrieveTokenViaSsh() + // check if the ssh-token only feature is enabled for this context for cli generally + sshTokenOnly, err := lConfig.GetFeature(lContext.Name, configFeaturePrefix, "ssh-token") if err != nil { return err } - - lc := lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current] - lc.Token = out - lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current] = lc - if err = writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)); err != nil { - return fmt.Errorf("couldn't write config: %v", err) - } - if err = versionCheck(lagoonCLIConfig.Current); err != nil { - return fmt.Errorf("couldn't check version: %v", err) + if lContext.ContextConfig.AuthenticationEndpoint == "" || sshTokenOnly { + // if no keycloak url is found in the config, perform a token request via ssh + // or the ssh-token override is set to enforce tokens via ssh (accounts in CI jobs) + out, err := retrieveTokenViaSsh() + if err != nil { + return err + } + lUser.UserConfig.Grant = out + } else { + // otherwise get a token via keycloak + token := &oauth2.Token{} + if lUser.UserConfig.Grant != nil { + token = lUser.UserConfig.Grant + } + _ = auth.TokenRequest(lContext.ContextConfig.AuthenticationEndpoint, "lagoon", "", token) + lUser.UserConfig.Grant = token } - - return nil + return lConfig.WriteConfig() } -func retrieveTokenViaSsh() (string, error) { +func retrieveTokenViaSsh() (*oauth2.Token, error) { skipAgent := false privateKey := fmt.Sprintf("%s/.ssh/id_rsa", userPath) // if the user has a key defined in their lagoon cli config, use it - if lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].SSHKey != "" { - privateKey = lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].SSHKey + if lUser.UserConfig.SSHKey != "" { + privateKey = lUser.UserConfig.SSHKey skipAgent = true } // otherwise check if one has been provided by the override flag @@ -139,7 +147,7 @@ func retrieveTokenViaSsh() (string, error) { privateKey = cmdSSHKey skipAgent = true } - authMethod, closeSSHAgent := publicKey(privateKey, cmdPubkeyIdentity, lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].PublicKeyIdentities, skipAgent) + authMethod, closeSSHAgent := publicKey(privateKey, cmdPubkeyIdentity, lUser.UserConfig.PublicKeyIdentities, skipAgent) config := &ssh.ClientConfig{ User: "lagoon", Auth: []ssh.AuthMethod{ @@ -149,23 +157,25 @@ func retrieveTokenViaSsh() (string, error) { } defer closeSSHAgent() - sshHost := fmt.Sprintf("%s:%s", - lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].HostName, - lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].Port) + sshHost := fmt.Sprintf("%s:%d", + lContext.ContextConfig.TokenHost, + lContext.ContextConfig.TokenPort) conn, err := ssh.Dial("tcp", sshHost, config) if err != nil { - return "", fmt.Errorf("unable to authenticate or connect to host %s\nthere may be an issue determining which ssh-key to use, or there may be an issue establishing a connection to the host\nthe error returned was: %v", sshHost, err) + return nil, fmt.Errorf("unable to authenticate or connect to host %s\nthere may be an issue determining which ssh-key to use, or there may be an issue establishing a connection to the host\nthe error returned was: %v", sshHost, err) } defer conn.Close() session, err := conn.NewSession() if err != nil { - return "", fmt.Errorf("unable to establish ssh session, error from attempt is: %v", err) + return nil, fmt.Errorf("unable to establish ssh session, error from attempt is: %v", err) } - out, err := session.CombinedOutput("token") + out, err := session.CombinedOutput("grant") if err != nil { - return "", fmt.Errorf("unable to get token: %v", err) + return nil, fmt.Errorf("unable to get token: %v", err) } - return strings.TrimSpace(string(out)), err + token := &oauth2.Token{} + json.Unmarshal(out, token) + return token, err } diff --git a/cmd/logs.go b/cmd/logs.go index edbf41aa..cf8d0234 100644 --- a/cmd/logs.go +++ b/cmd/logs.go @@ -59,18 +59,16 @@ func generateLogsCommand(service, container string, lines uint, } func getSSHHostPort(environmentName string, debug bool) (string, string, error) { - current := lagoonCLIConfig.Current - // set the default ssh host and port to the core ssh endpoint - sshHost := lagoonCLIConfig.Lagoons[current].HostName - sshPort := lagoonCLIConfig.Lagoons[current].Port - token := lagoonCLIConfig.Lagoons[current].Token + sshHost := lContext.ContextConfig.TokenHost + sshPort := fmt.Sprintf("%d", lContext.ContextConfig.TokenPort) - // get SSH Portal endpoint if required + // if the config for this lagoon is set to use ssh portal support, handle that here + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) ctx, cancel := context.WithTimeout(context.Background(), connTimeout) defer cancel() @@ -97,8 +95,8 @@ func getSSHClientConfig(environmentName string) (*ssh.ClientConfig, skipAgent := false privateKey := fmt.Sprintf("%s/.ssh/id_rsa", userPath) // check for user-defined key - if lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].SSHKey != "" { - privateKey = lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].SSHKey + if lUser.UserConfig.SSHKey != "" { + privateKey = lUser.UserConfig.SSHKey skipAgent = true } // check for specified key @@ -112,7 +110,7 @@ func getSSHClientConfig(environmentName string) (*ssh.ClientConfig, return nil, nil, fmt.Errorf("couldn't get ~/.ssh/known_hosts: %v", err) } // configure an SSH client session - authMethod, closeSSHAgent := publicKey(privateKey, cmdPubkeyIdentity, lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].PublicKeyIdentities, skipAgent) + authMethod, closeSSHAgent := publicKey(privateKey, cmdPubkeyIdentity, lUser.UserConfig.PublicKeyIdentities, skipAgent) return &ssh.ClientConfig{ User: cmdProjectName + "-" + environmentName, Auth: []ssh.AuthMethod{authMethod}, @@ -126,7 +124,7 @@ var logsCmd = &cobra.Command{ Short: "Display logs for a service of an environment and project", RunE: func(cmd *cobra.Command, args []string) error { // validate/refresh token - validateToken(lagoonCLIConfig.Current) + validateToken(lContext.Name) // validate and parse arguments if cmdProjectName == "" || cmdProjectEnvironment == "" { return fmt.Errorf( diff --git a/cmd/notificationsemail.go b/cmd/notificationsemail.go index bdd62a1a..a56aba3d 100644 --- a/cmd/notificationsemail.go +++ b/cmd/notificationsemail.go @@ -20,7 +20,7 @@ This command is used to set up a new email notification in Lagoon. This requires It does not configure a project to send notifications to email though, you need to use project-email for that.`, Aliases: []string{"e"}, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -43,13 +43,12 @@ It does not configure a project to send notifications to email though, you need return err } if yesNo(fmt.Sprintf("You are attempting to create an email notification '%s' with email address '%s', are you sure?", name, email)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := schema.AddNotificationEmailInput{ @@ -99,7 +98,7 @@ var addProjectNotificationEmailCmd = &cobra.Command{ Long: `Add an email notification to a project This command is used to add an existing email notification in Lagoon to a project.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -115,13 +114,12 @@ This command is used to add an existing email notification in Lagoon to a projec return err } if yesNo(fmt.Sprintf("You are attempting to add email notification '%s' to project '%s', are you sure?", name, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.AddNotificationToProjectInput{ NotificationType: schema.EmailNotification, @@ -146,7 +144,7 @@ var listProjectEmailsCmd = &cobra.Command{ Aliases: []string{"pe"}, Short: "List email details about a project (alias: pe)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -156,14 +154,12 @@ var listProjectEmailsCmd = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName); err != nil { return err } - - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.GetProjectNotificationEmail(context.TODO(), cmdProjectName, lc) @@ -201,20 +197,19 @@ var listAllEmailsCmd = &cobra.Command{ Aliases: []string{"e"}, Short: "List all email notification details (alias: e)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.GetAllNotificationEmail(context.TODO(), lc) if err != nil { @@ -250,7 +245,7 @@ var deleteProjectEmailNotificationCmd = &cobra.Command{ Aliases: []string{"pe"}, Short: "Delete a email notification from a project", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -265,13 +260,12 @@ var deleteProjectEmailNotificationCmd = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete email notification '%s' from project '%s', are you sure?", name, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.RemoveNotificationFromProjectInput{ NotificationType: schema.EmailNotification, @@ -296,7 +290,7 @@ var deleteEmailNotificationCmd = &cobra.Command{ Aliases: []string{"e"}, Short: "Delete an email notification from Lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -311,13 +305,12 @@ var deleteEmailNotificationCmd = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete email notification '%s', are you sure?", name)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.DeleteNotificationEmail(context.TODO(), name, lc) if err != nil { @@ -337,7 +330,7 @@ var updateEmailNotificationCmd = &cobra.Command{ Aliases: []string{"e"}, Short: "Update an existing email notification", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -368,13 +361,12 @@ var updateEmailNotificationCmd = &cobra.Command{ } if yesNo(fmt.Sprintf("You are attempting to update email notification '%s', are you sure?", name)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.UpdateNotificationEmailInput{ diff --git a/cmd/notificationsrocketchat.go b/cmd/notificationsrocketchat.go index f1130028..8c9fc932 100644 --- a/cmd/notificationsrocketchat.go +++ b/cmd/notificationsrocketchat.go @@ -21,7 +21,7 @@ var addNotificationRocketchatCmd = &cobra.Command{ This command is used to set up a new RocketChat notification in Lagoon. This requires information to talk to RocketChat like the webhook URL and the name of the channel. It does not configure a project to send notifications to RocketChat though, you need to use project-rocketchat for that.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -48,13 +48,12 @@ It does not configure a project to send notifications to RocketChat though, you return err } if yesNo(fmt.Sprintf("You are attempting to create an RocketChat notification '%s' with webhook '%s' channel '%s', are you sure?", name, webhook, channel)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := schema.AddNotificationRocketChatInput{ @@ -107,7 +106,7 @@ var addProjectNotificationRocketChatCmd = &cobra.Command{ Long: `Add a RocketChat notification to a project This command is used to add an existing RocketChat notification in Lagoon to a project.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -122,13 +121,12 @@ This command is used to add an existing RocketChat notification in Lagoon to a p return err } if yesNo(fmt.Sprintf("You are attempting to add RocketChat notification '%s' to project '%s', are you sure?", name, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.AddNotificationToProjectInput{ @@ -155,7 +153,7 @@ var listProjectRocketChatsCmd = &cobra.Command{ Aliases: []string{"pr"}, Short: "List RocketChats details about a project (alias: pr)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -165,14 +163,12 @@ var listProjectRocketChatsCmd = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName); err != nil { return err } - - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.GetProjectNotificationRocketChat(context.TODO(), cmdProjectName, lc) @@ -212,20 +208,19 @@ var listAllRocketChatsCmd = &cobra.Command{ Aliases: []string{"r"}, Short: "List all RocketChats notification details (alias: r)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.GetAllNotificationRocketChat(context.TODO(), lc) if err != nil { @@ -263,7 +258,7 @@ var deleteProjectRocketChatNotificationCmd = &cobra.Command{ Aliases: []string{"pr"}, Short: "Delete a RocketChat notification from a project", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -278,13 +273,12 @@ var deleteProjectRocketChatNotificationCmd = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete RocketChat notification '%s' from project '%s', are you sure?", name, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.RemoveNotificationFromProjectInput{ NotificationType: schema.RocketChatNotification, @@ -309,7 +303,7 @@ var deleteRocketChatNotificationCmd = &cobra.Command{ Aliases: []string{"r"}, Short: "Delete a RocketChat notification from Lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -324,13 +318,12 @@ var deleteRocketChatNotificationCmd = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete RocketChat notification '%s', are you sure?", name)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.DeleteNotificationRocketChat(context.TODO(), name, lc) if err != nil { @@ -350,7 +343,7 @@ var updateRocketChatNotificationCmd = &cobra.Command{ Aliases: []string{"r"}, Short: "Update an existing RocketChat notification", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -386,13 +379,12 @@ var updateRocketChatNotificationCmd = &cobra.Command{ } if yesNo(fmt.Sprintf("You are attempting to update RocketChat notification '%s', are you sure?", name)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.UpdateNotificationRocketChatInput{ diff --git a/cmd/notificationsslack.go b/cmd/notificationsslack.go index 7032f3a2..f4dcd3b8 100644 --- a/cmd/notificationsslack.go +++ b/cmd/notificationsslack.go @@ -21,7 +21,7 @@ var addNotificationSlackCmd = &cobra.Command{ This command is used to set up a new Slack notification in Lagoon. This requires information to talk to Slack like the webhook URL and the name of the channel. It does not configure a project to send notifications to Slack though, you need to use project-slack for that.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -48,13 +48,12 @@ It does not configure a project to send notifications to Slack though, you need return err } if yesNo(fmt.Sprintf("You are attempting to create an Slack notification '%s' with webhook '%s' channel '%s', are you sure?", name, webhook, channel)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := schema.AddNotificationSlackInput{ @@ -107,7 +106,7 @@ var addProjectNotificationSlackCmd = &cobra.Command{ Long: `Add a Slack notification to a project This command is used to add an existing Slack notification in Lagoon to a project.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -122,13 +121,12 @@ This command is used to add an existing Slack notification in Lagoon to a projec return err } if yesNo(fmt.Sprintf("You are attempting to add Slack notification '%s' to project '%s', are you sure?", name, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.AddNotificationToProjectInput{ NotificationType: schema.SlackNotification, @@ -153,7 +151,7 @@ var listProjectSlacksCmd = &cobra.Command{ Aliases: []string{"ps"}, Short: "List Slacks details about a project (alias: ps)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -163,14 +161,12 @@ var listProjectSlacksCmd = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName); err != nil { return err } - - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.GetProjectNotificationSlack(context.TODO(), cmdProjectName, lc) @@ -210,20 +206,19 @@ var listAllSlacksCmd = &cobra.Command{ Aliases: []string{"s"}, Short: "List all Slacks notification details (alias: s)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.GetAllNotificationSlack(context.TODO(), lc) if err != nil { @@ -261,7 +256,7 @@ var deleteProjectSlackNotificationCmd = &cobra.Command{ Aliases: []string{"ps"}, Short: "Delete a Slack notification from a project", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -276,13 +271,12 @@ var deleteProjectSlackNotificationCmd = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete Slack notification '%s' from project '%s', are you sure?", name, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.RemoveNotificationFromProjectInput{ NotificationType: schema.SlackNotification, @@ -307,7 +301,7 @@ var deleteSlackNotificationCmd = &cobra.Command{ Aliases: []string{"s"}, Short: "Delete a Slack notification from Lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -322,13 +316,12 @@ var deleteSlackNotificationCmd = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete Slack notification '%s', are you sure?", name)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.DeleteNotificationSlack(context.TODO(), name, lc) if err != nil { @@ -348,7 +341,7 @@ var updateSlackNotificationCmd = &cobra.Command{ Aliases: []string{"s"}, Short: "Update an existing Slack notification", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -384,15 +377,13 @@ var updateSlackNotificationCmd = &cobra.Command{ } if yesNo(fmt.Sprintf("You are attempting to update Slack notification '%s', are you sure?", name)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) - notification := &schema.UpdateNotificationSlackInput{ Name: name, Patch: patch, diff --git a/cmd/notificationsteams.go b/cmd/notificationsteams.go index d267fb66..d267586d 100644 --- a/cmd/notificationsteams.go +++ b/cmd/notificationsteams.go @@ -21,7 +21,7 @@ This command is used to set up a new Microsoft Teams notification in Lagoon. Thi It does not configure a project to send notifications to Microsoft Teams though, you need to use project-microsoftteams for that.`, Aliases: []string{"m"}, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -44,13 +44,12 @@ It does not configure a project to send notifications to Microsoft Teams though, return err } if yesNo(fmt.Sprintf("You are attempting to create a Microsoft Teams notification '%s' with webhook url '%s', are you sure?", name, webhook)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := schema.AddNotificationMicrosoftTeamsInput{ @@ -100,7 +99,7 @@ var addProjectNotificationMicrosoftTeamsCmd = &cobra.Command{ Long: `Add a Microsoft Teams notification to a project This command is used to add an existing Microsoft Teams notification in Lagoon to a project.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -115,13 +114,12 @@ This command is used to add an existing Microsoft Teams notification in Lagoon t return err } if yesNo(fmt.Sprintf("You are attempting to add Microsoft Teams notification '%s' to project '%s', are you sure?", name, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.AddNotificationToProjectInput{ NotificationType: schema.MicrosoftTeamsNotification, @@ -146,7 +144,7 @@ var listProjectMicrosoftTeamsCmd = &cobra.Command{ Aliases: []string{"pm"}, Short: "List Microsoft Teams details about a project (alias: pm)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -156,14 +154,12 @@ var listProjectMicrosoftTeamsCmd = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName); err != nil { return err } - - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.GetProjectNotificationMicrosoftTeams(context.TODO(), cmdProjectName, lc) @@ -201,20 +197,19 @@ var listAllMicrosoftTeamsCmd = &cobra.Command{ Aliases: []string{"m"}, Short: "List all Microsoft Teams notification details (alias: m)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.GetAllNotificationMicrosoftTeams(context.TODO(), lc) if err != nil { @@ -250,7 +245,7 @@ var deleteProjectMicrosoftTeamsNotificationCmd = &cobra.Command{ Aliases: []string{"pm"}, Short: "Delete a Microsoft Teams notification from a project", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -265,13 +260,12 @@ var deleteProjectMicrosoftTeamsNotificationCmd = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete Microsoft Teams notification '%s' from project '%s', are you sure?", name, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.RemoveNotificationFromProjectInput{ NotificationType: schema.MicrosoftTeamsNotification, @@ -296,7 +290,7 @@ var deleteMicrosoftTeamsNotificationCmd = &cobra.Command{ Aliases: []string{"m"}, Short: "Delete a Microsoft Teams notification from Lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -311,13 +305,12 @@ var deleteMicrosoftTeamsNotificationCmd = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete Microsoft Teams notification '%s', are you sure?", name)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.DeleteNotificationMicrosoftTeams(context.TODO(), name, lc) if err != nil { @@ -337,7 +330,7 @@ var updateMicrosoftTeamsNotificationCmd = &cobra.Command{ Aliases: []string{"m"}, Short: "Update an existing Microsoft Teams notification", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -368,13 +361,12 @@ var updateMicrosoftTeamsNotificationCmd = &cobra.Command{ } if yesNo(fmt.Sprintf("You are attempting to update Microsoft Teams notification '%s', are you sure?", name)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.UpdateNotificationMicrosoftTeamsInput{ diff --git a/cmd/notificationswebhook.go b/cmd/notificationswebhook.go index 58eee15a..e6424cef 100644 --- a/cmd/notificationswebhook.go +++ b/cmd/notificationswebhook.go @@ -21,7 +21,7 @@ This command is used to set up a new webhook notification in Lagoon. This requir It does not configure a project to send notifications to webhook though, you need to use project-webhook for that.`, Aliases: []string{"w"}, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -44,13 +44,12 @@ It does not configure a project to send notifications to webhook though, you nee return err } if yesNo(fmt.Sprintf("You are attempting to create a webhook notification '%s' with webhook url '%s', are you sure?", name, webhook)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := schema.AddNotificationWebhookInput{ @@ -100,7 +99,7 @@ var addProjectNotificationWebhookCmd = &cobra.Command{ Long: `Add a webhook notification to a project This command is used to add an existing webhook notification in Lagoon to a project.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -115,13 +114,12 @@ This command is used to add an existing webhook notification in Lagoon to a proj return err } if yesNo(fmt.Sprintf("You are attempting to add webhook notification '%s' to project '%s', are you sure?", name, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.AddNotificationToProjectInput{ NotificationType: schema.WebhookNotification, @@ -146,7 +144,7 @@ var listProjectWebhooksCmd = &cobra.Command{ Aliases: []string{"pw"}, Short: "List webhook details about a project (alias: pw)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -156,14 +154,12 @@ var listProjectWebhooksCmd = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName); err != nil { return err } - - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.GetProjectNotificationWebhook(context.TODO(), cmdProjectName, lc) @@ -201,20 +197,19 @@ var listAllWebhooksCmd = &cobra.Command{ Aliases: []string{"w"}, Short: "List all webhook notification details (alias: w)", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.GetAllNotificationWebhook(context.TODO(), lc) if err != nil { @@ -250,7 +245,7 @@ var deleteProjectWebhookNotificationCmd = &cobra.Command{ Aliases: []string{"pw"}, Short: "Delete a webhook notification from a project", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -265,13 +260,12 @@ var deleteProjectWebhookNotificationCmd = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete webhook notification '%s' from project '%s', are you sure?", name, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.RemoveNotificationFromProjectInput{ NotificationType: schema.WebhookNotification, @@ -296,7 +290,7 @@ var deleteWebhookNotificationCmd = &cobra.Command{ Aliases: []string{"w"}, Short: "Delete a webhook notification from Lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -311,13 +305,12 @@ var deleteWebhookNotificationCmd = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete webhook notification '%s', are you sure?", name)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.DeleteNotificationWebhook(context.TODO(), name, lc) if err != nil { @@ -337,7 +330,7 @@ var updateWebhookNotificationCmd = &cobra.Command{ Aliases: []string{"w"}, Short: "Update an existing webhook notification", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -368,13 +361,12 @@ var updateWebhookNotificationCmd = &cobra.Command{ } if yesNo(fmt.Sprintf("You are attempting to update webhook notification '%s', are you sure?", name)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) notification := &schema.UpdateNotificationWebhookInput{ diff --git a/cmd/organization.go b/cmd/organization.go index 1685a2b9..a7ef72ba 100644 --- a/cmd/organization.go +++ b/cmd/organization.go @@ -16,7 +16,7 @@ var addOrganizationCmd = &cobra.Command{ Aliases: []string{"o"}, Short: "Add a new organization to Lagoon", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -59,13 +59,12 @@ var addOrganizationCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organizationInput := schema.AddOrganizationInput{ @@ -100,7 +99,7 @@ var deleteOrganizationCmd = &cobra.Command{ Aliases: []string{"o"}, Short: "Delete an organization", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -115,13 +114,12 @@ var deleteOrganizationCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) @@ -150,7 +148,7 @@ var updateOrganizationCmd = &cobra.Command{ Aliases: []string{"o"}, Short: "Update an organization", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -193,13 +191,12 @@ var updateOrganizationCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) diff --git a/cmd/project.go b/cmd/project.go index c6432f57..f28ae724 100644 --- a/cmd/project.go +++ b/cmd/project.go @@ -33,13 +33,12 @@ var deleteProjectCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) if yesNo(fmt.Sprintf("You are attempting to delete project '%s', are you sure?", cmdProjectName)) { @@ -62,7 +61,7 @@ var addProjectCmd = &cobra.Command{ Short: "Add a new project to Lagoon, or add a project to an organization", Long: "To add a project to an organization, you'll need to include the `organization` flag and provide the name of the organization. You need to be an owner of this organization to do this.\nIf you're the organization owner and want to grant yourself ownership to this project to be able to deploy environments, specify the `owner` flag.", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -143,13 +142,12 @@ var addProjectCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) projectInput := schema.AddProjectInput{ @@ -314,13 +312,12 @@ var updateProjectCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) projectPatch := schema.UpdateProjectPatchInput{ @@ -423,13 +420,12 @@ var listProjectByMetadata = &cobra.Command{ if err := requiredInputCheck("Key", key); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) projects, err := lagoon.GetProjectsByMetadata(context.TODO(), key, value, lc) if err != nil { @@ -483,13 +479,12 @@ var getProjectMetadata = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetProjectMetadata(context.TODO(), cmdProjectName, lc) if err != nil { @@ -542,13 +537,12 @@ var updateProjectMetadata = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to update key '%s' for project '%s' metadata, are you sure?", key, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { @@ -598,13 +592,12 @@ var deleteProjectMetadataByKey = &cobra.Command{ return err } if yesNo(fmt.Sprintf("You are attempting to delete key '%s' from project '%s' metadata, are you sure?", key, cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) if err != nil { @@ -640,7 +633,7 @@ var removeProjectFromOrganizationCmd = &cobra.Command{ Short: "Remove a project from an Organization", Long: "Removes a project from an Organization, but does not delete the project.\nThis is used by platform administrators to be able to reset a project.", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -656,13 +649,12 @@ var removeProjectFromOrganizationCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) diff --git a/cmd/raw.go b/cmd/raw.go index ef96ec95..885b97f8 100644 --- a/cmd/raw.go +++ b/cmd/raw.go @@ -30,13 +30,12 @@ The output of this command will be the JSON response from the API`, if err := requiredInputCheck("Raw query or mutation", raw); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) if err != nil { return err diff --git a/cmd/retrieve.go b/cmd/retrieve.go index eec279bb..8c72bfad 100644 --- a/cmd/retrieve.go +++ b/cmd/retrieve.go @@ -15,7 +15,7 @@ var retrieveCmd = &cobra.Command{ Aliases: []string{"re", "ret"}, Short: "Trigger a retrieval operation on backups", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } @@ -28,7 +28,7 @@ var retrieveBackupCmd = &cobra.Command{ Given a backup-id, you can initiate a retrieval for it. You can check the status of the backup using the list backups or get backup command.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -43,13 +43,12 @@ You can check the status of the backup using the list backups or get backup comm return err } if yesNo(fmt.Sprintf("You are attempting to trigger a retrieval for backup ID '%s', are you sure?", backupID)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.AddBackupRestore(context.TODO(), backupID, lc) if err != nil { diff --git a/cmd/root.go b/cmd/root.go index 2d1ed184..3804f3e6 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -3,23 +3,21 @@ package cmd import ( "bufio" - "context" "fmt" "net" "os" - "path/filepath" "strings" "time" + "github.com/adrg/xdg" "github.com/golang-jwt/jwt" "github.com/manifoldco/promptui" "github.com/spf13/cobra" "github.com/spf13/cobra/doc" - lagooncli "github.com/uselagoon/lagoon-cli/internal/lagoon" - "github.com/uselagoon/lagoon-cli/internal/lagoon/client" "github.com/uselagoon/lagoon-cli/pkg/app" "github.com/uselagoon/lagoon-cli/pkg/output" "github.com/uselagoon/lagoon-cli/pkg/updatecheck" + config "github.com/uselagoon/machinery/utils/config" ) var cmdProject app.LagoonProject @@ -41,9 +39,16 @@ var verboseOutput bool var skipUpdateCheck bool -// global for the lagoon config that the cli uses -// @TODO: when lagoon-cli rewrite happens, do this a bit better -var lagoonCLIConfig lagooncli.Config +// configv2 related globals +var lConfig *config.Config +var lContext *config.Context +var lUser *config.User +var configFeaturePrefix = "cli" +var cliFeatures = []string{ + "environment-from-directory", // feature that enables the sourcing of project/environment from within a git repository + "disable-update-check", // feature that disables the automatic update check + "ssh-token", // feature that forces the cli to use ssh token base authentication instead of keycloak based +} // version/build information (populated at build time by make file) var ( @@ -57,13 +62,17 @@ var rootCmd = &cobra.Command{ Short: "Command line integration for Lagoon", Long: `Lagoon CLI. Manage your Lagoon hosted projects.`, DisableAutoGenTag: true, - PersistentPreRun: func(cmd *cobra.Command, args []string) { - if lagoonCLIConfig.UpdateCheckDisable { - skipUpdateCheck = true + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + skipUpdateCheck, err := lConfig.GetFeature(lContext.Name, configFeaturePrefix, "disable-update-check") + if err != nil { + return err } if !skipUpdateCheck { + updateFile, err := xdg.StateFile(fmt.Sprintf("%s/%s", "lagoon", "update")) + if err != nil { + return err + } // Using code from https://github.com/drud/ddev/ - updateFile := filepath.Join(userPath, ".lagoon.update") // Do periodic detection of whether an update is available for lagoon-cli users. timeToCheckForUpdates, err := updatecheck.IsUpdateNeeded(updateFile, updateInterval) if err != nil { @@ -78,31 +87,29 @@ var rootCmd = &cobra.Command{ updateNeeded, updateURL, err := updatecheck.AvailableUpdates("uselagoon", "lagoon-cli", lagoonCLIVersion) if err != nil { output.RenderInfo("Could not check for updates. This is most often caused by a networking issue.", outputOptions) - output.RenderError(err.Error(), outputOptions) - return + return err } if updateNeeded { output.RenderInfo(fmt.Sprintf("A new update is available! please visit %s to download the update.\nFor upgrade help see %s\n\nIf installed using brew, upgrade using `brew upgrade lagoon`\n", updateURL, updateDocURL), outputOptions) } } } + return nil }, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { if docsFlag { err := doc.GenMarkdownTree(cmd, "docs/commands") if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) + return err } fmt.Println("Documentation updated") - return + return nil } if versionFlag { displayVersionInfo() - return + return nil } - cmd.Help() - os.Exit(1) + return fmt.Errorf("no command provided") }, } @@ -118,7 +125,7 @@ func Execute() { // internet connection. It just tries a quick DNS query. // This requires that the named record be query-able. func isInternetActive() bool { - _, err := net.LookupHost("amazee.io") + _, err := net.LookupHost("lagoon.sh") return err == nil } @@ -180,11 +187,9 @@ Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} `) rootCmd.AddCommand(addCmd) - rootCmd.AddCommand(configCmd) rootCmd.AddCommand(deleteCmd) rootCmd.AddCommand(deployCmd) rootCmd.AddCommand(getCmd) - rootCmd.AddCommand(kibanaCmd) rootCmd.AddCommand(listCmd) rootCmd.AddCommand(loginCmd) rootCmd.AddCommand(runCmd) @@ -192,12 +197,12 @@ Use "{{.CommandPath}} [command] --help" for more information about a command.{{e rootCmd.AddCommand(updateCmd) rootCmd.AddCommand(retrieveCmd) rootCmd.AddCommand(versionCmd) - rootCmd.AddCommand(webCmd) rootCmd.AddCommand(importCmd) rootCmd.AddCommand(exportCmd) rootCmd.AddCommand(whoamiCmd) rootCmd.AddCommand(uploadCmd) rootCmd.AddCommand(rawCmd) + rootCmd.AddCommand(configCmd) rootCmd.AddCommand(resetPasswordCmd) rootCmd.AddCommand(logsCmd) } @@ -218,27 +223,61 @@ func displayVersionInfo() { func initConfig() { var err error - // Find home directory. - userPath, err = os.UserHomeDir() + // load or prompt user to create configuration + lConfig, err = config.LoadConfig(createConfig) if err != nil { - output.RenderError(fmt.Errorf("couldn't get $HOME: %v", err).Error(), outputOptions) - os.Exit(1) - } - configFilePath = userPath - - // check if we are being given a path to a different config file - err = getLagoonConfigFile(&configFilePath, &configName, &configExtension, createConfig, rootCmd) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) + // if there is no new config format + if strings.Contains(err.Error(), "could not locate `config.yaml`") { + // check for a legacy config + data, err2 := readLegacyConfig() + noConfig := false + if err2 != nil { + noConfig = true + } + if len(data) > 0 { + if yn("Only a legacy configuration file was found, would you like to convert it to the new format?") { + convertConfig(true) + fmt.Println("Configuration converted") + os.Exit(0) + } else { + noConfig = true + } + } + if noConfig { + if yn("Unable to find configuration, would you like to create one?") { + err := createInitialConfig() + if err != nil { + output.RenderError(err.Error(), outputOptions) + os.Exit(1) + } + fmt.Println("Configuration created") + os.Exit(0) + } + output.RenderError("No configuration created, configuration is required to use the CLI", outputOptions) + os.Exit(1) + } + } else { + output.RenderError(fmt.Sprintf("Unable to detect or load configuration: %s", err.Error()), outputOptions) + os.Exit(1) + } } - - err = readLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) + if cmdLagoon == "" { + // source the default context for the config + lContext, err = lConfig.GetDefaultContext() + if err != nil { + output.RenderError(err.Error(), outputOptions) + os.Exit(1) + } + } else { + // otherwise try find the one the user has provided + lContext, err = lConfig.GetContext(cmdLagoon) + if err != nil { + output.RenderError(err.Error(), outputOptions) + os.Exit(1) + } } - err = getLagoonContext(&lagoonCLIConfig, &cmdLagoon, rootCmd) + // get the users details for the context + lUser, err = lConfig.GetUser(lContext.User) if err != nil { output.RenderError(err.Error(), outputOptions) os.Exit(1) @@ -247,8 +286,13 @@ func initConfig() { // if the directory or repository you're in has a valid .lagoon.yml and docker-compose.yml with x-lagoon-project in it // we can use that inplaces where projects already exist so you don't have to type it out // and environments too - // this option is opt-in now, so to use it you will need to `lagoon config feature --enable-local-dir-check=true` - if lagoonCLIConfig.EnvironmentFromDirectory { + // this option is opt-in and will be deprecated in the future + envFromDir, err := lConfig.GetFeature(lContext.Name, configFeaturePrefix, "environment-from-directory") + if err != nil { + output.RenderError(err.Error(), outputOptions) + os.Exit(1) + } + if envFromDir { cmdProject, _ = app.GetLocalProject() } if cmdProject.Name != "" && cmdProjectName == "" { @@ -261,20 +305,24 @@ func initConfig() { func yesNo(message string) bool { if !forceAction { - prompt := promptui.Select{ - Label: message + "; Select[Yes/No]", - Items: []string{"No", "Yes"}, - } - _, result, err := prompt.Run() - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } - return result == "Yes" + return yn(message) } return true } +func yn(message string) bool { + prompt := promptui.Select{ + Label: message + "; Select[Yes/No]", + Items: []string{"No", "Yes"}, + } + _, result, err := prompt.Run() + if err != nil { + output.RenderError(err.Error(), outputOptions) + os.Exit(1) + } + return result == "Yes" +} + // GetInput reads input from an input buffer and returns the result as a string. func GetInput() string { inputScanner.Scan() @@ -299,12 +347,7 @@ const ( ) func validateToken(lagoon string) { - var err error - if err = checkContextExists(&lagoonCLIConfig); err != nil { - fmt.Println(err) - os.Exit(1) - } - valid := VerifyTokenExpiry(&lagoonCLIConfig, lagoon) + valid := VerifyTokenExpiry(lUser.UserConfig.Grant.AccessToken, lagoon) if !valid { loginErr := loginToken() if loginErr != nil { @@ -319,10 +362,7 @@ func validateToken(lagoon string) { // error instead of exiting on error. func validateTokenE(lagoon string) error { var err error - if err = checkContextExists(&lagoonCLIConfig); err != nil { - return err - } - if VerifyTokenExpiry(&lagoonCLIConfig, lagoon) { + if VerifyTokenExpiry(lUser.UserConfig.Grant.AccessToken, lagoon) { // check the API for the version of lagoon if we haven't got one set // otherwise return nil, nothing to do return nil @@ -335,110 +375,15 @@ func validateTokenE(lagoon string) error { return nil } -// check if we have a version set in config, if not get the version. -// this checks whenever a token is refreshed -func versionCheck(lagoon string) error { - lc := client.New( - lagoonCLIConfig.Lagoons[lagoon].GraphQL, - lagoonCLIConfig.Lagoons[lagoon].Token, - lagoonCLIConfig.Lagoons[lagoon].Version, - lagoonCLIVersion, - debugEnable) - lagoonVersion, err := lagooncli.GetLagoonAPIVersion(context.TODO(), lc) - if err != nil { - return err - } - l := lagoonCLIConfig.Lagoons[lagoon] - l.Version = lagoonVersion.LagoonVersion - lagoonCLIConfig.Lagoons[lagoon] = l - if err = writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)); err != nil { - return fmt.Errorf("couldn't write config: %v", err) - } - return nil -} - -func getLagoonConfigFile(configPath *string, configName *string, configExtension *string, createConfig bool, cmd *cobra.Command) error { - // check if we have an envvar or flag to define our confg file - var configFilePath string - configFilePath, err := cmd.Flags().GetString("config-file") - if err != nil { - return fmt.Errorf("error reading flag `config-file`: %v", err) - } - if configFilePath == "" { - if lagoonConfigEnvar, ok := os.LookupEnv("LAGOONCONFIG"); ok { - configFilePath = lagoonConfigEnvar - } - // prefer LAGOON_CONFIG_FILE - if lagoonConfigEnvar, ok := os.LookupEnv("LAGOON_CONFIG_FILE"); ok { - configFilePath = lagoonConfigEnvar - } - } - if configFilePath != "" { - if fileExists(configFilePath) || createConfig { - *configPath = filepath.Dir(configFilePath) - *configExtension = filepath.Ext(configFilePath) - *configName = strings.TrimSuffix(filepath.Base(configFilePath), *configExtension) - return nil - } - return fmt.Errorf("%s/%s File doesn't exist", *configPath, configFilePath) - - } - // no config file found - return nil -} - -func getLagoonContext(lagoonCLIConfig *lagooncli.Config, lagoon *string, cmd *cobra.Command) error { - // check if we have an envvar or flag to define our lagoon context - var lagoonContext string - lagoonContext, err := cmd.Flags().GetString("lagoon") - if err != nil { - return fmt.Errorf("error reading flag `lagoon`: %v", err) - } - if lagoonContext == "" { - if lagoonContextEnvar, ok := os.LookupEnv("LAGOONCONTEXT"); ok { - lagoonContext = lagoonContextEnvar - } - // prefer LAGOON_CONTEXT - if lagoonContextEnvar, ok := os.LookupEnv("LAGOON_CONTEXT"); ok { - configFilePath = lagoonContextEnvar - } - } - if lagoonContext != "" { - *lagoon = lagoonContext - } else { - if lagoonCLIConfig.Default == "" { - *lagoon = "amazeeio" - } else { - *lagoon = lagoonCLIConfig.Default - } - } - // set the Current lagoon to the one we've determined it needs to be - lagoonCLIConfig.Current = strings.TrimSpace(*lagoon) - return nil -} - -func checkContextExists(lagoonCLIConfig *lagooncli.Config) error { - contextExists := false - for l := range lagoonCLIConfig.Lagoons { - if l == lagoonCLIConfig.Current { - contextExists = true - } - } - if !contextExists { - return fmt.Errorf("chosen context '%s' doesn't exist in config file", lagoonCLIConfig.Current) - } - return nil -} - // VerifyTokenExpiry verfies if the current token is valid or not -func VerifyTokenExpiry(lc *lagooncli.Config, lagoon string) bool { +func VerifyTokenExpiry(token, lagoon string) bool { var p jwt.Parser - token, _, err := p.ParseUnverified( - lc.Lagoons[lagoon].Token, &jwt.StandardClaims{}) + token2, _, err := p.ParseUnverified( + token, &jwt.StandardClaims{}) if err != nil { return false } - if token.Claims.Valid() != nil { + if token2.Claims.Valid() != nil { return false } return true diff --git a/cmd/run.go b/cmd/run.go index e22d4538..255d7aa6 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -9,7 +9,7 @@ var runCmd = &cobra.Command{ Aliases: []string{"r"}, Short: "Run a task against an environment", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } diff --git a/cmd/shared.go b/cmd/shared.go index 2cc479d1..9f8f20f0 100644 --- a/cmd/shared.go +++ b/cmd/shared.go @@ -8,15 +8,6 @@ import ( "github.com/uselagoon/lagoon-cli/pkg/output" ) -// config vars -var lagoonHostname string -var lagoonPort string -var lagoonGraphQL string -var lagoonToken string -var lagoonUI string -var lagoonKibana string -var lagoonSSHKey string - // group vars var groupName string diff --git a/cmd/ssh.go b/cmd/ssh.go index 003b5dee..d9b5bced 100644 --- a/cmd/ssh.go +++ b/cmd/ssh.go @@ -39,19 +39,18 @@ var sshEnvCmd = &cobra.Command{ // run the environment through the makesafe and shorted functions that lagoon uses environmentName := makeSafe(shortenEnvironment(cmdProjectName, cmdProjectEnvironment)) - current := lagoonCLIConfig.Current // set the default ssh host and port to the core ssh endpoint - sshHost := lagoonCLIConfig.Lagoons[current].HostName - sshPort := lagoonCLIConfig.Lagoons[current].Port + sshHost := lContext.ContextConfig.TokenHost + sshPort := fmt.Sprintf("%d", lContext.ContextConfig.TokenPort) isPortal := false // if the config for this lagoon is set to use ssh portal support, handle that here - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetSSHEndpointsByProject(context.TODO(), cmdProjectName, lc) if err != nil { @@ -75,8 +74,8 @@ var sshEnvCmd = &cobra.Command{ privateKey := fmt.Sprintf("%s/.ssh/id_rsa", userPath) // if the user has a key defined in their lagoon cli config, use it - if lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].SSHKey != "" { - privateKey = lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].SSHKey + if lUser.UserConfig.SSHKey != "" { + privateKey = lUser.UserConfig.SSHKey skipAgent = true } // otherwise check if one has been provided by the override flag @@ -95,7 +94,7 @@ var sshEnvCmd = &cobra.Command{ } else { // start an interactive ssh session - authMethod, closeSSHAgent := publicKey(privateKey, cmdPubkeyIdentity, lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].PublicKeyIdentities, skipAgent) + authMethod, closeSSHAgent := publicKey(privateKey, cmdPubkeyIdentity, lUser.UserConfig.PublicKeyIdentities, skipAgent) config := &ssh.ClientConfig{ User: sshConfig["username"], Auth: []ssh.AuthMethod{ diff --git a/cmd/tasks.go b/cmd/tasks.go index 3b28c0e4..887e7fc5 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -24,7 +24,7 @@ var getTaskByID = &cobra.Command{ Long: `Get information about a task by its ID`, Aliases: []string{"t", "tbi"}, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -43,13 +43,12 @@ var getTaskByID = &cobra.Command{ if err := requiredInputCheck("ID", strconv.Itoa(taskID)); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.TaskByID(context.TODO(), taskID, lc) if err != nil { @@ -92,7 +91,7 @@ You should only run this once and then check the status of the task that gets cr If the task fails or fails to update, contact your Lagoon administrator for assistance.`, Aliases: []string{"as", "standby"}, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -103,19 +102,18 @@ If the task fails or fails to update, contact your Lagoon administrator for assi return err } if yesNo(fmt.Sprintf("You are attempting to run the active/standby switch for project '%s', are you sure?", cmdProjectName)) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.ActiveStandbySwitch(context.TODO(), cmdProjectName, lc) if err != nil { return err } - fmt.Printf("Created a new task with ID %d \nYou can use the following command to query the task status: \nlagoon -l %s get task-by-id --id %d --logs \n", result.ID, current, result.ID) + fmt.Printf("Created a new task with ID %d \nYou can use the following command to query the task status: \nlagoon -l %s get task-by-id --id %d --logs \n", result.ID, lContext.Name, result.ID) } return nil }, @@ -126,7 +124,7 @@ var runDrushArchiveDump = &cobra.Command{ Aliases: []string{"dard"}, Short: "Run a drush archive dump on an environment", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -136,13 +134,12 @@ var runDrushArchiveDump = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) if err != nil { return err @@ -194,7 +191,7 @@ var runDrushSQLDump = &cobra.Command{ Aliases: []string{"dsqld"}, Short: "Run a drush sql dump on an environment", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -204,13 +201,12 @@ var runDrushSQLDump = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) if err != nil { return err @@ -262,7 +258,7 @@ var runDrushCacheClear = &cobra.Command{ Aliases: []string{"dcc"}, Short: "Run a drush cache clear on an environment", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -272,13 +268,12 @@ var runDrushCacheClear = &cobra.Command{ if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) if err != nil { return err @@ -335,7 +330,7 @@ Direct: lagoon run invoke -p example -e main -N "advanced task name" `, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -350,13 +345,12 @@ Direct: return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) project, err := lagoon.GetProjectByName(context.TODO(), cmdProjectName, lc) @@ -409,7 +403,7 @@ Path: lagoon run custom -p example -e main -N "My Task" -S cli -s /path/to/my-script.sh `, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -457,13 +451,12 @@ Path: if err := requiredInputCheck("Project name", cmdProjectName, "Environment name", cmdProjectEnvironment, "Task command", taskCommand, "Task name", taskName, "Task service", taskService); err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) task := schema.Task{ @@ -500,7 +493,7 @@ var uploadFilesToTask = &cobra.Command{ Long: `Upload files to a task by its ID`, Aliases: []string{"tf"}, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -519,13 +512,12 @@ var uploadFilesToTask = &cobra.Command{ if err != nil { return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) result, err := lagoon.UploadFilesForTask(context.TODO(), taskID, files, lc) if err != nil { diff --git a/cmd/update.go b/cmd/update.go index 12106614..17d15130 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -9,7 +9,7 @@ var updateCmd = &cobra.Command{ Aliases: []string{"u"}, Short: "Update a resource", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } @@ -18,7 +18,7 @@ var updateNotificationCmd = &cobra.Command{ Aliases: []string{"n"}, Short: "List all notifications or notifications on projects", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } diff --git a/cmd/upload.go b/cmd/upload.go index 33049ae0..88222d1d 100644 --- a/cmd/upload.go +++ b/cmd/upload.go @@ -9,7 +9,7 @@ var uploadCmd = &cobra.Command{ Aliases: []string{"u"}, Short: "Upload files to tasks", PersistentPreRun: func(cmd *cobra.Command, args []string) { - validateToken(lagoonCLIConfig.Current) // get a new token if the current one is invalid + validateToken(lContext.Name) // get a new token if the current one is invalid }, } diff --git a/cmd/users.go b/cmd/users.go index 8b0d05b9..3ca0625f 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -95,13 +95,12 @@ var addUserCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) userInput := &schema.AddUserInput{ @@ -175,13 +174,12 @@ Add key by defining key value, but not specifying a key name (will default to tr return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) userSSHKey, err := parseSSHKeyFile(pubKeyFile, sshKeyName, pubKeyValue, email) @@ -224,13 +222,12 @@ var deleteSSHKeyCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) if yesNo(fmt.Sprintf("You are attempting to delete SSH key ID:'%d', are you sure?", sshKeyID)) { @@ -267,13 +264,12 @@ var deleteUserCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) deleteUserInput := &schema.DeleteUserInput{ @@ -331,13 +327,12 @@ var updateUserCmd = &cobra.Command{ return nil } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) currentUser := &schema.UpdateUserInput{ @@ -389,13 +384,12 @@ var getUserKeysCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) userKeys, err := lagoon.GetUserSSHKeysByEmail(context.TODO(), userEmail, lc) if err != nil { @@ -447,13 +441,12 @@ var getAllUserKeysCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) groupMembers, err := lagoon.ListAllGroupMembersWithKeys(context.TODO(), groupName, lc) if err != nil { @@ -503,7 +496,7 @@ var addAdministratorToOrganizationCmd = &cobra.Command{ Short: "Add an administrator to an Organization", Long: "Add an administrator to an Organization. If the role flag is not provided users will be added as viewers", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -537,13 +530,12 @@ var addAdministratorToOrganizationCmd = &cobra.Command{ return fmt.Errorf(`role '%s' is not valid - valid roles include "viewer", "owner"`, role) } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) @@ -578,7 +570,7 @@ var removeAdministratorFromOrganizationCmd = &cobra.Command{ Aliases: []string{"org-admin"}, Short: "Remove an administrator from an Organization", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -601,13 +593,12 @@ var removeAdministratorFromOrganizationCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) organization, err := lagoon.GetOrganizationByName(context.TODO(), organizationName, lc) @@ -646,7 +637,7 @@ var resetPasswordCmd = &cobra.Command{ Aliases: []string{"reset-pass", "rp"}, Short: "Send a password reset email", PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -661,13 +652,12 @@ var resetPasswordCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) resetPasswordInput := schema.ResetUserPasswordInput{ diff --git a/cmd/variables.go b/cmd/variables.go index 88e6bc5a..59d5ce25 100644 --- a/cmd/variables.go +++ b/cmd/variables.go @@ -41,13 +41,12 @@ var addVariableCmd = &cobra.Command{ return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) in := &schema.EnvVariableByNameInput{ @@ -122,13 +121,12 @@ var deleteVariableCmd = &cobra.Command{ deleteMsg = fmt.Sprintf("You are attempting to delete variable '%s' from environment '%s' in project '%s', are you sure?", varName, cmdProjectEnvironment, cmdProjectName) } if yesNo(deleteMsg) { - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) in := &schema.DeleteEnvVariableByNameInput{ Project: cmdProjectName, diff --git a/cmd/web.go b/cmd/web.go deleted file mode 100644 index e052a5a0..00000000 --- a/cmd/web.go +++ /dev/null @@ -1,55 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - "strings" - - "github.com/pkg/browser" - "github.com/spf13/cobra" - "github.com/uselagoon/lagoon-cli/pkg/output" -) - -var webCmd = &cobra.Command{ - Use: "web", - Aliases: []string{"w"}, - Short: "Launch the web user interface", - Run: func(cmd *cobra.Command, args []string) { - if cmdProjectName == "" { - fmt.Println("Missing arguments: Project name is not defined") - cmd.Help() - os.Exit(1) - } - - urlBuilder := strings.Builder{} - urlBuilder.WriteString(lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].UI) - if lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].UI != "" { - urlBuilder.WriteString(fmt.Sprintf("/projects/%s", cmdProjectName)) - } else { - output.RenderError("unable to determine url for ui, is one set?", outputOptions) - os.Exit(1) - } - - url := urlBuilder.String() - fmt.Printf("Opening %s\n", url) - _ = browser.OpenURL(url) - }, -} - -var kibanaCmd = &cobra.Command{ - Use: "kibana", - Aliases: []string{"k"}, - Short: "Launch the kibana interface", - Run: func(cmd *cobra.Command, args []string) { - urlBuilder := strings.Builder{} - urlBuilder.WriteString(lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].Kibana) - if lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].Kibana == "" { - output.RenderError("unable to determine url for kibana, is one set?", outputOptions) - os.Exit(1) - } - - url := urlBuilder.String() - fmt.Printf("Opening %s\n", url) - _ = browser.OpenURL(url) - }, -} diff --git a/cmd/whoami.go b/cmd/whoami.go index d8193548..69dee268 100644 --- a/cmd/whoami.go +++ b/cmd/whoami.go @@ -20,7 +20,7 @@ var whoamiCmd = &cobra.Command{ Long: `Whoami will return your user information for lagoon. This is useful if you have multiple keys or accounts in multiple lagoons and need to check which you are using.`, PreRunE: func(_ *cobra.Command, _ []string) error { - return validateTokenE(lagoonCLIConfig.Current) + return validateTokenE(lContext.Name) }, RunE: func(cmd *cobra.Command, args []string) error { debug, err := cmd.Flags().GetBool("debug") @@ -32,13 +32,12 @@ This is useful if you have multiple keys or accounts in multiple lagoons and nee return err } - current := lagoonCLIConfig.Current - token := lagoonCLIConfig.Lagoons[current].Token + utoken := lUser.UserConfig.Grant.AccessToken lc := lclient.New( - lagoonCLIConfig.Lagoons[current].GraphQL, + fmt.Sprintf("%s/graphql", lContext.ContextConfig.APIHostname), lagoonCLIVersion, - lagoonCLIConfig.Lagoons[current].Version, - &token, + lContext.ContextConfig.Version, + &utoken, debug) user, err := lagoon.Me(context.TODO(), lc) diff --git a/docs/commands/lagoon.md b/docs/commands/lagoon.md index bbe54f1f..89a6dd0b 100644 --- a/docs/commands/lagoon.md +++ b/docs/commands/lagoon.md @@ -36,13 +36,12 @@ lagoon [flags] * [lagoon add](lagoon_add.md) - Add a project, or add notifications and variables to projects or environments * [lagoon completion](lagoon_completion.md) - Generate the autocompletion script for the specified shell -* [lagoon config](lagoon_config.md) - Configure Lagoon CLI +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon * [lagoon delete](lagoon_delete.md) - Delete a project, or delete notifications and variables from projects or environments * [lagoon deploy](lagoon_deploy.md) - Actions for deploying or promoting branches or environments in lagoon * [lagoon export](lagoon_export.md) - Export lagoon output to yaml * [lagoon get](lagoon_get.md) - Get info on a resource * [lagoon import](lagoon_import.md) - Import a config from a yaml file -* [lagoon kibana](lagoon_kibana.md) - Launch the kibana interface * [lagoon list](lagoon_list.md) - List projects, environments, deployments, variables or notifications * [lagoon login](lagoon_login.md) - Log into a Lagoon instance * [lagoon logs](lagoon_logs.md) - Display logs for a service of an environment and project @@ -54,6 +53,5 @@ lagoon [flags] * [lagoon update](lagoon_update.md) - Update a resource * [lagoon upload](lagoon_upload.md) - Upload files to tasks * [lagoon version](lagoon_version.md) - Version information -* [lagoon web](lagoon_web.md) - Launch the web user interface * [lagoon whoami](lagoon_whoami.md) - Whoami will return your user information for lagoon diff --git a/docs/commands/lagoon_add_project-rocketchat.md b/docs/commands/lagoon_add_project-rocketchat.md deleted file mode 100644 index 346a7962..00000000 --- a/docs/commands/lagoon_add_project-rocketchat.md +++ /dev/null @@ -1,41 +0,0 @@ -## lagoon add project-rocketchat - -Add a Rocket.Chat notification to a project - -### Synopsis - -Add a Rocket.Chat notification to a project -This command is used to add an existing Rocket.Chat notification in Lagoon to a project. - -``` -lagoon add project-rocketchat [flags] -``` - -### Options - -``` - -h, --help help for project-rocketchat - -n, --name string The name of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon add](lagoon_add.md) - Add a project, or add notifications and variables to projects or environments - diff --git a/docs/commands/lagoon_add_project-slack.md b/docs/commands/lagoon_add_project-slack.md deleted file mode 100644 index 1252eab7..00000000 --- a/docs/commands/lagoon_add_project-slack.md +++ /dev/null @@ -1,41 +0,0 @@ -## lagoon add project-slack - -Add a Slack notification to a project - -### Synopsis - -Add a Slack notification to a project -This command is used to add an existing Slack notification in Lagoon to a project. - -``` -lagoon add project-slack [flags] -``` - -### Options - -``` - -h, --help help for project-slack - -n, --name string The name of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon add](lagoon_add.md) - Add a project, or add notifications and variables to projects or environments - diff --git a/docs/commands/lagoon_add_restore.md b/docs/commands/lagoon_add_restore.md deleted file mode 100644 index d0af9e87..00000000 --- a/docs/commands/lagoon_add_restore.md +++ /dev/null @@ -1,42 +0,0 @@ -## lagoon add restore - -Restore a backup - -### Synopsis - -Restore a backup -Given a backup-id, you can initiate a restore for it. -You can check the status of the backup using the list backups or get backup command. - -``` -lagoon add restore [flags] -``` - -### Options - -``` - -B, --backup-id string The backup ID you want to restore - -h, --help help for restore -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon add](lagoon_add.md) - Add a project, or add notifications and variables to projects or environments - diff --git a/docs/commands/lagoon_add_rocketchat.md b/docs/commands/lagoon_add_rocketchat.md deleted file mode 100644 index 0ee19004..00000000 --- a/docs/commands/lagoon_add_rocketchat.md +++ /dev/null @@ -1,44 +0,0 @@ -## lagoon add rocketchat - -Add a new Rocket.Chat notification - -### Synopsis - -Add a new Rocket.Chat notification -This command is used to set up a new Rocket.Chat notification in Lagoon. This requires information to talk to Rocket.Chat like the webhook URL and the name of the channel. -It does not configure a project to send notifications to Rocket.Chat though, you need to use project-rocketchat for that. - -``` -lagoon add rocketchat [flags] -``` - -### Options - -``` - -c, --channel string The channel for the notification - -h, --help help for rocketchat - -n, --name string The name of the notification - -w, --webhook string The webhook URL of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon add](lagoon_add.md) - Add a project, or add notifications and variables to projects or environments - diff --git a/docs/commands/lagoon_add_slack.md b/docs/commands/lagoon_add_slack.md deleted file mode 100644 index 5c10a24d..00000000 --- a/docs/commands/lagoon_add_slack.md +++ /dev/null @@ -1,44 +0,0 @@ -## lagoon add slack - -Add a new Slack notification - -### Synopsis - -Add a new Slack notification -This command is used to set up a new Slack notification in Lagoon. This requires information to talk to Slack like the webhook URL and the name of the channel. -It does not configure a project to send notifications to Slack though, you need to use project-slack for that. - -``` -lagoon add slack [flags] -``` - -### Options - -``` - -c, --channel string The channel for the notification - -h, --help help for slack - -n, --name string The name of the notification - -w, --webhook string The webhook URL of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon add](lagoon_add.md) - Add a project, or add notifications and variables to projects or environments - diff --git a/docs/commands/lagoon_add_variable.md b/docs/commands/lagoon_add_variable.md deleted file mode 100644 index c95d3d90..00000000 --- a/docs/commands/lagoon_add_variable.md +++ /dev/null @@ -1,43 +0,0 @@ -## lagoon add variable - -Add a variable to an environment or project - -### Synopsis - -Add a variable to an environment or project - -``` -lagoon add variable [flags] -``` - -### Options - -``` - -h, --help help for variable - -j, --json string JSON string to patch - -N, --name string Name of the variable to add - -S, --scope string Scope of the variable[global, build, runtime, container_registry, internal_container_registry] - -V, --value string Value of the variable to add -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon add](lagoon_add.md) - Add a project, or add notifications and variables to projects or environments - diff --git a/docs/commands/lagoon_config.md b/docs/commands/lagoon_config.md deleted file mode 100644 index e2663d7c..00000000 --- a/docs/commands/lagoon_config.md +++ /dev/null @@ -1,41 +0,0 @@ -## lagoon config - -Configure Lagoon CLI - -### Options - -``` - -h, --help help for config -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication - --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. - This will override any public key identities defined in configuration - -v, --verbose Enable verbose output to stderr (if supported) -``` - -### SEE ALSO - -* [lagoon](lagoon.md) - Command line integration for Lagoon -* [lagoon config add](lagoon_config_add.md) - Add information about an additional Lagoon instance to use -* [lagoon config current](lagoon_config_current.md) - Display the current Lagoon that commands would be executed against -* [lagoon config default](lagoon_config_default.md) - Set the default Lagoon to use -* [lagoon config delete](lagoon_config_delete.md) - Delete a Lagoon instance configuration -* [lagoon config feature](lagoon_config_feature.md) - Enable or disable CLI features -* [lagoon config lagoon-version](lagoon_config_lagoon-version.md) - Checks the current Lagoon for its version and sets it in the config file -* [lagoon config list](lagoon_config_list.md) - View all configured Lagoon instances - diff --git a/docs/commands/lagoon_config_add.md b/docs/commands/lagoon_config_add.md deleted file mode 100644 index 4654c871..00000000 --- a/docs/commands/lagoon_config_add.md +++ /dev/null @@ -1,46 +0,0 @@ -## lagoon config add - -Add information about an additional Lagoon instance to use - -``` -lagoon config add [flags] -``` - -### Options - -``` - --create-config Create the config file if it is non existent (to be used with --config-file) - -g, --graphql string Lagoon GraphQL endpoint - -h, --help help for add - -H, --hostname string Lagoon SSH hostname - -k, --kibana string Lagoon Kibana URL (https://logs.amazeeio.cloud) - -P, --port string Lagoon SSH port - --publickey-identityfile strings Specific public key identity files to use when doing ssh-agent checks (support multiple) - --ssh-key string SSH Key to use for this cluster for generating tokens - -t, --token string Lagoon GraphQL token - -u, --ui string Lagoon UI location (https://dashboard.amazeeio.cloud) -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. - This will override any public key identities defined in configuration - -v, --verbose Enable verbose output to stderr (if supported) -``` - -### SEE ALSO - -* [lagoon config](lagoon_config.md) - Configure Lagoon CLI - diff --git a/docs/commands/lagoon_config_list.md b/docs/commands/lagoon_config_list.md deleted file mode 100644 index b12f5aa9..00000000 --- a/docs/commands/lagoon_config_list.md +++ /dev/null @@ -1,39 +0,0 @@ -## lagoon config list - -View all configured Lagoon instances - -``` -lagoon config list [flags] -``` - -### Options - -``` - -h, --help help for list - --show-full Show full config output when listing Lagoon configurations -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication - --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. - This will override any public key identities defined in configuration - -v, --verbose Enable verbose output to stderr (if supported) -``` - -### SEE ALSO - -* [lagoon config](lagoon_config.md) - Configure Lagoon CLI - diff --git a/docs/commands/lagoon_configuration.md b/docs/commands/lagoon_configuration.md new file mode 100644 index 00000000..1e61a177 --- /dev/null +++ b/docs/commands/lagoon_configuration.md @@ -0,0 +1,44 @@ +## lagoon configuration + +Manage or view the contexts and users for interacting with Lagoon + +### Options + +``` + -h, --help help for configuration +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication + --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. + This will override any public key identities defined in configuration + -v, --verbose Enable verbose output to stderr (if supported) +``` + +### SEE ALSO + +* [lagoon](lagoon.md) - Command line integration for Lagoon +* [lagoon configuration add-context](lagoon_configuration_add-context.md) - Add a new Lagoon context +* [lagoon configuration add-user](lagoon_configuration_add-user.md) - Add a new Lagoon context user +* [lagoon configuration config-path](lagoon_configuration_config-path.md) - Get the path of where the config file lives +* [lagoon configuration convert-config](lagoon_configuration_convert-config.md) - Convert legacy .lagoon.yml config to the new configuration format +* [lagoon configuration default-context](lagoon_configuration_default-context.md) - Change which context is the default +* [lagoon configuration feature](lagoon_configuration_feature.md) - Enable or disable a feature for all contexts or a specific context +* [lagoon configuration list-contexts](lagoon_configuration_list-contexts.md) - View all configured Lagoon contexts +* [lagoon configuration list-users](lagoon_configuration_list-users.md) - View all configured Lagoon context users +* [lagoon configuration update-context](lagoon_configuration_update-context.md) - Update a Lagoon context +* [lagoon configuration update-user](lagoon_configuration_update-user.md) - Update a Lagoon context user + diff --git a/docs/commands/lagoon_configuration_add-context.md b/docs/commands/lagoon_configuration_add-context.md new file mode 100644 index 00000000..570748c6 --- /dev/null +++ b/docs/commands/lagoon_configuration_add-context.md @@ -0,0 +1,46 @@ +## lagoon configuration add-context + +Add a new Lagoon context + +``` +lagoon configuration add-context [flags] +``` + +### Options + +``` + --api-hostname string Lagoon API hostname (eg: https://api.lagoon.sh) + --authentication-hostname string Lagoon authentication hostname (eg: https://keycloak.lagoon.sh) + -h, --help help for add-context + --name string The name to reference this context as + --token-hostname string Lagoon Token endpoint hostname (eg: token.lagoon.sh) + --token-port int Lagoon Token endpoint port (eg: 22) + --ui-hostname string Lagoon UI hostname (eg: https://ui.lagoon.sh) + --user string The user to associate to this context + --webhook-hostname string Lagoon webhook hostname (eg: https://webhook.lagoon.sh) +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication + --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. + This will override any public key identities defined in configuration + -v, --verbose Enable verbose output to stderr (if supported) +``` + +### SEE ALSO + +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon + diff --git a/docs/commands/lagoon_configuration_add-user.md b/docs/commands/lagoon_configuration_add-user.md new file mode 100644 index 00000000..7b906dc5 --- /dev/null +++ b/docs/commands/lagoon_configuration_add-user.md @@ -0,0 +1,39 @@ +## lagoon configuration add-user + +Add a new Lagoon context user + +``` +lagoon configuration add-user [flags] +``` + +### Options + +``` + -h, --help help for add-user + --name string The name to reference this user as + --ssh-key string The full path to this users ssh-key +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. + This will override any public key identities defined in configuration + -v, --verbose Enable verbose output to stderr (if supported) +``` + +### SEE ALSO + +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon + diff --git a/docs/commands/lagoon_config_current.md b/docs/commands/lagoon_configuration_config-path.md similarity index 81% rename from docs/commands/lagoon_config_current.md rename to docs/commands/lagoon_configuration_config-path.md index ca3f87e2..34d21b40 100644 --- a/docs/commands/lagoon_config_current.md +++ b/docs/commands/lagoon_configuration_config-path.md @@ -1,15 +1,15 @@ -## lagoon config current +## lagoon configuration config-path -Display the current Lagoon that commands would be executed against +Get the path of where the config file lives ``` -lagoon config current [flags] +lagoon configuration config-path [flags] ``` ### Options ``` - -h, --help help for current + -h, --help help for config-path ``` ### Options inherited from parent commands @@ -34,5 +34,5 @@ lagoon config current [flags] ### SEE ALSO -* [lagoon config](lagoon_config.md) - Configure Lagoon CLI +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon diff --git a/docs/commands/lagoon_configuration_convert-config.md b/docs/commands/lagoon_configuration_convert-config.md new file mode 100644 index 00000000..be6ce0b3 --- /dev/null +++ b/docs/commands/lagoon_configuration_convert-config.md @@ -0,0 +1,46 @@ +## lagoon configuration convert-config + +Convert legacy .lagoon.yml config to the new configuration format + +### Synopsis + +Convert legacy .lagoon.yml config to the new configuration format. +This will prompt you to provide any required information if it is missing from your legacy configuration. +Running this command initially will run in dry-run mode, if you're happy with the result you can run it again +with the --write-config flag to save the new configuration. + +``` +lagoon configuration convert-config [flags] +``` + +### Options + +``` + -h, --help help for convert-config + --write-config Whether the config should be written to the config file or not +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication + --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. + This will override any public key identities defined in configuration + -v, --verbose Enable verbose output to stderr (if supported) +``` + +### SEE ALSO + +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon + diff --git a/docs/commands/lagoon_config_default.md b/docs/commands/lagoon_configuration_default-context.md similarity index 77% rename from docs/commands/lagoon_config_default.md rename to docs/commands/lagoon_configuration_default-context.md index 6599ae93..af76a1db 100644 --- a/docs/commands/lagoon_config_default.md +++ b/docs/commands/lagoon_configuration_default-context.md @@ -1,15 +1,16 @@ -## lagoon config default +## lagoon configuration default-context -Set the default Lagoon to use +Change which context is the default ``` -lagoon config default [flags] +lagoon configuration default-context [flags] ``` ### Options ``` - -h, --help help for default + -h, --help help for default-context + --name string The name of the context to be default ``` ### Options inherited from parent commands @@ -34,5 +35,5 @@ lagoon config default [flags] ### SEE ALSO -* [lagoon config](lagoon_config.md) - Configure Lagoon CLI +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon diff --git a/docs/commands/lagoon_config_feature.md b/docs/commands/lagoon_configuration_feature.md similarity index 66% rename from docs/commands/lagoon_config_feature.md rename to docs/commands/lagoon_configuration_feature.md index 40c178b8..70efa674 100644 --- a/docs/commands/lagoon_config_feature.md +++ b/docs/commands/lagoon_configuration_feature.md @@ -1,17 +1,18 @@ -## lagoon config feature +## lagoon configuration feature -Enable or disable CLI features +Enable or disable a feature for all contexts or a specific context ``` -lagoon config feature [flags] +lagoon configuration feature [flags] ``` ### Options ``` - --disable-update-check string Enable or disable checking of updates (true/false) - --enable-local-dir-check string Enable or disable checking of local directory for Lagoon project (true/false) - -h, --help help for feature + --context string If provided the feature will be enabled for this context, otherwise globally + --feature string The name of the feature to enable or disable [environment-from-directory,disable-update-check,ssh-token] + -h, --help help for feature + --state The state of the feature (--state=true or --state=false) ``` ### Options inherited from parent commands @@ -36,5 +37,5 @@ lagoon config feature [flags] ### SEE ALSO -* [lagoon config](lagoon_config.md) - Configure Lagoon CLI +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon diff --git a/docs/commands/lagoon_config_delete.md b/docs/commands/lagoon_configuration_list-contexts.md similarity index 81% rename from docs/commands/lagoon_config_delete.md rename to docs/commands/lagoon_configuration_list-contexts.md index 06b5b2c0..119f5e8d 100644 --- a/docs/commands/lagoon_config_delete.md +++ b/docs/commands/lagoon_configuration_list-contexts.md @@ -1,15 +1,15 @@ -## lagoon config delete +## lagoon configuration list-contexts -Delete a Lagoon instance configuration +View all configured Lagoon contexts ``` -lagoon config delete [flags] +lagoon configuration list-contexts [flags] ``` ### Options ``` - -h, --help help for delete + -h, --help help for list-contexts ``` ### Options inherited from parent commands @@ -34,5 +34,5 @@ lagoon config delete [flags] ### SEE ALSO -* [lagoon config](lagoon_config.md) - Configure Lagoon CLI +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon diff --git a/docs/commands/lagoon_config_lagoon-version.md b/docs/commands/lagoon_configuration_list-users.md similarity index 81% rename from docs/commands/lagoon_config_lagoon-version.md rename to docs/commands/lagoon_configuration_list-users.md index 4ff546ae..23326614 100644 --- a/docs/commands/lagoon_config_lagoon-version.md +++ b/docs/commands/lagoon_configuration_list-users.md @@ -1,15 +1,15 @@ -## lagoon config lagoon-version +## lagoon configuration list-users -Checks the current Lagoon for its version and sets it in the config file +View all configured Lagoon context users ``` -lagoon config lagoon-version [flags] +lagoon configuration list-users [flags] ``` ### Options ``` - -h, --help help for lagoon-version + -h, --help help for list-users ``` ### Options inherited from parent commands @@ -34,5 +34,5 @@ lagoon config lagoon-version [flags] ### SEE ALSO -* [lagoon config](lagoon_config.md) - Configure Lagoon CLI +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon diff --git a/docs/commands/lagoon_configuration_update-context.md b/docs/commands/lagoon_configuration_update-context.md new file mode 100644 index 00000000..b8fdfe86 --- /dev/null +++ b/docs/commands/lagoon_configuration_update-context.md @@ -0,0 +1,46 @@ +## lagoon configuration update-context + +Update a Lagoon context + +``` +lagoon configuration update-context [flags] +``` + +### Options + +``` + --api-hostname string Lagoon API hostname (eg: https://api.lagoon.sh) + --authentication-hostname string Lagoon authentication hostname (eg: https://keycloak.lagoon.sh) + -h, --help help for update-context + --name string The name to reference this context as + --token-hostname string Lagoon Token endpoint hostname (eg: token.lagoon.sh) + --token-port int Lagoon Token endpoint port (eg: 22) + --ui-hostname string Lagoon UI hostname (eg: https://ui.lagoon.sh) + --user string The user to associate to this context + --webhook-hostname string Lagoon webhook hostname (eg: https://webhook.lagoon.sh) +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication + --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. + This will override any public key identities defined in configuration + -v, --verbose Enable verbose output to stderr (if supported) +``` + +### SEE ALSO + +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon + diff --git a/docs/commands/lagoon_configuration_update-user.md b/docs/commands/lagoon_configuration_update-user.md new file mode 100644 index 00000000..96ea1920 --- /dev/null +++ b/docs/commands/lagoon_configuration_update-user.md @@ -0,0 +1,39 @@ +## lagoon configuration update-user + +Update a Lagoon context user + +``` +lagoon configuration update-user [flags] +``` + +### Options + +``` + -h, --help help for update-user + --name string The name to reference this user as + --ssh-key string The full path to this users ssh-key +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. + This will override any public key identities defined in configuration + -v, --verbose Enable verbose output to stderr (if supported) +``` + +### SEE ALSO + +* [lagoon configuration](lagoon_configuration.md) - Manage or view the contexts and users for interacting with Lagoon + diff --git a/docs/commands/lagoon_delete_project-by-metadata.md b/docs/commands/lagoon_delete_project-by-metadata.md deleted file mode 100644 index 66bf1aca..00000000 --- a/docs/commands/lagoon_delete_project-by-metadata.md +++ /dev/null @@ -1,40 +0,0 @@ -## lagoon delete project-by-metadata - -Delete a key from a projects metadata - -### Synopsis - -Delete a key from a projects metadata - -``` -lagoon delete project-by-metadata [flags] -``` - -### Options - -``` - -h, --help help for project-by-metadata - --key string The key name of the metadata value you are querying on -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon delete](lagoon_delete.md) - Delete a project, or delete notifications and variables from projects or environments - diff --git a/docs/commands/lagoon_delete_project-email.md b/docs/commands/lagoon_delete_project-email.md deleted file mode 100644 index 030d9eec..00000000 --- a/docs/commands/lagoon_delete_project-email.md +++ /dev/null @@ -1,40 +0,0 @@ -## lagoon delete project-email - -Delete a Email notification from a project - -### Synopsis - -Delete a Email notification from a project - -``` -lagoon delete project-email [flags] -``` - -### Options - -``` - -h, --help help for project-email - -n, --name string The name of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon delete](lagoon_delete.md) - Delete a project, or delete notifications and variables from projects or environments - diff --git a/docs/commands/lagoon_delete_project-microsoftteams.md b/docs/commands/lagoon_delete_project-microsoftteams.md deleted file mode 100644 index d593daa0..00000000 --- a/docs/commands/lagoon_delete_project-microsoftteams.md +++ /dev/null @@ -1,40 +0,0 @@ -## lagoon delete project-microsoftteams - -Delete a MicrosoftTeams notification from a project - -### Synopsis - -Delete a MicrosoftTeams notification from a project - -``` -lagoon delete project-microsoftteams [flags] -``` - -### Options - -``` - -h, --help help for project-microsoftteams - -n, --name string The name of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon delete](lagoon_delete.md) - Delete a project, or delete notifications and variables from projects or environments - diff --git a/docs/commands/lagoon_delete_project-rocketchat.md b/docs/commands/lagoon_delete_project-rocketchat.md deleted file mode 100644 index a1c16850..00000000 --- a/docs/commands/lagoon_delete_project-rocketchat.md +++ /dev/null @@ -1,40 +0,0 @@ -## lagoon delete project-rocketchat - -Delete a Rocket.Chat notification from a project - -### Synopsis - -Delete a Rocket.Chat notification from a project - -``` -lagoon delete project-rocketchat [flags] -``` - -### Options - -``` - -h, --help help for project-rocketchat - -n, --name string The name of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon delete](lagoon_delete.md) - Delete a project, or delete notifications and variables from projects or environments - diff --git a/docs/commands/lagoon_delete_project-slack.md b/docs/commands/lagoon_delete_project-slack.md deleted file mode 100644 index 541063e1..00000000 --- a/docs/commands/lagoon_delete_project-slack.md +++ /dev/null @@ -1,40 +0,0 @@ -## lagoon delete project-slack - -Delete a Slack notification from a project - -### Synopsis - -Delete a Slack notification from a project - -``` -lagoon delete project-slack [flags] -``` - -### Options - -``` - -h, --help help for project-slack - -n, --name string The name of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon delete](lagoon_delete.md) - Delete a project, or delete notifications and variables from projects or environments - diff --git a/docs/commands/lagoon_delete_project-webhook.md b/docs/commands/lagoon_delete_project-webhook.md deleted file mode 100644 index a0f34f36..00000000 --- a/docs/commands/lagoon_delete_project-webhook.md +++ /dev/null @@ -1,40 +0,0 @@ -## lagoon delete project-webhook - -Delete a Webhook notification from a project - -### Synopsis - -Delete a Webhook notification from a project - -``` -lagoon delete project-webhook [flags] -``` - -### Options - -``` - -h, --help help for project-webhook - -n, --name string The name of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon delete](lagoon_delete.md) - Delete a project, or delete notifications and variables from projects or environments - diff --git a/docs/commands/lagoon_delete_rocketchat.md b/docs/commands/lagoon_delete_rocketchat.md deleted file mode 100644 index 90b1d0dd..00000000 --- a/docs/commands/lagoon_delete_rocketchat.md +++ /dev/null @@ -1,40 +0,0 @@ -## lagoon delete rocketchat - -Delete a Rocket.Chat notification from Lagoon - -### Synopsis - -Delete a Rocket.Chat notification from Lagoon - -``` -lagoon delete rocketchat [flags] -``` - -### Options - -``` - -h, --help help for rocketchat - -n, --name string The name of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon delete](lagoon_delete.md) - Delete a project, or delete notifications and variables from projects or environments - diff --git a/docs/commands/lagoon_delete_slack.md b/docs/commands/lagoon_delete_slack.md deleted file mode 100644 index b53a07e3..00000000 --- a/docs/commands/lagoon_delete_slack.md +++ /dev/null @@ -1,40 +0,0 @@ -## lagoon delete slack - -Delete a Slack notification from Lagoon - -### Synopsis - -Delete a Slack notification from Lagoon - -``` -lagoon delete slack [flags] -``` - -### Options - -``` - -h, --help help for slack - -n, --name string The name of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon delete](lagoon_delete.md) - Delete a project, or delete notifications and variables from projects or environments - diff --git a/docs/commands/lagoon_get_project-by-metadata.md b/docs/commands/lagoon_get_project-by-metadata.md deleted file mode 100644 index f0d0679c..00000000 --- a/docs/commands/lagoon_get_project-by-metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -## lagoon get project-by-metadata - -Query lagoon projects by a given metadata key or key:value - -### Synopsis - -Query lagoon projects by a given metadata key or key:value - -``` -lagoon get project-by-metadata [flags] -``` - -### Options - -``` - -h, --help help for project-by-metadata - --key string The key name of the metadata value you are querying on - --value string The value for the key you are querying on -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon get](lagoon_get.md) - Get info on a resource - diff --git a/docs/commands/lagoon_kibana.md b/docs/commands/lagoon_kibana.md deleted file mode 100644 index 6274fa59..00000000 --- a/docs/commands/lagoon_kibana.md +++ /dev/null @@ -1,38 +0,0 @@ -## lagoon kibana - -Launch the kibana interface - -``` -lagoon kibana [flags] -``` - -### Options - -``` - -h, --help help for kibana -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication - --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. - This will override any public key identities defined in configuration - -v, --verbose Enable verbose output to stderr (if supported) -``` - -### SEE ALSO - -* [lagoon](lagoon.md) - Command line integration for Lagoon - diff --git a/docs/commands/lagoon_list_project-by-metadata.md b/docs/commands/lagoon_list_project-by-metadata.md deleted file mode 100644 index 74c6ebed..00000000 --- a/docs/commands/lagoon_list_project-by-metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -## lagoon list project-by-metadata - -List projects by a given metadata key or key:value - -### Synopsis - -List projects by a given metadata key or key:value - -``` -lagoon list project-by-metadata [flags] -``` - -### Options - -``` - -h, --help help for project-by-metadata - --key string The key name of the metadata value you are querying on - --value string The value for the key you are querying on -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon list](lagoon_list.md) - List projects, deployments, variables or notifications - diff --git a/docs/commands/lagoon_list_rocketchat.md b/docs/commands/lagoon_list_rocketchat.md deleted file mode 100644 index 15e3b129..00000000 --- a/docs/commands/lagoon_list_rocketchat.md +++ /dev/null @@ -1,39 +0,0 @@ -## lagoon list rocketchat - -List Rocket.Chat details about a project (alias: r) - -### Synopsis - -List Rocket.Chat details about a project (alias: r) - -``` -lagoon list rocketchat [flags] -``` - -### Options - -``` - -h, --help help for rocketchat -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon list](lagoon_list.md) - List projects, deployments, variables or notifications - diff --git a/docs/commands/lagoon_list_slack.md b/docs/commands/lagoon_list_slack.md deleted file mode 100644 index ab67a6cc..00000000 --- a/docs/commands/lagoon_list_slack.md +++ /dev/null @@ -1,39 +0,0 @@ -## lagoon list slack - -List Slack details about a project (alias: s) - -### Synopsis - -List Slack details about a project (alias: s) - -``` -lagoon list slack [flags] -``` - -### Options - -``` - -h, --help help for slack -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon list](lagoon_list.md) - List projects, deployments, variables or notifications - diff --git a/docs/commands/lagoon_list_users.md b/docs/commands/lagoon_list_users.md deleted file mode 100644 index 7988ae11..00000000 --- a/docs/commands/lagoon_list_users.md +++ /dev/null @@ -1,40 +0,0 @@ -## lagoon list users - -List all users in groups (alias: u) - -### Synopsis - -List all users in groups in lagoon, this only shows users that are in groups. - -``` -lagoon list users [flags] -``` - -### Options - -``` - -h, --help help for users - -N, --name string Name of the group to list users in (if not specified, will default to all groups) -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon list](lagoon_list.md) - List projects, environments, deployments, variables or notifications - diff --git a/docs/commands/lagoon_update_project-by-metadata.md b/docs/commands/lagoon_update_project-by-metadata.md deleted file mode 100644 index 3d29503f..00000000 --- a/docs/commands/lagoon_update_project-by-metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -## lagoon update project-by-metadata - -Update a projects metadata with a given key or key:value - -### Synopsis - -Update a projects metadata with a given key or key:value - -``` -lagoon update project-by-metadata [flags] -``` - -### Options - -``` - -h, --help help for project-by-metadata - --key string The key name of the metadata value you are querying on - --value string The value for the key you are querying on -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon update](lagoon_update.md) - Update a resource - diff --git a/docs/commands/lagoon_update_rocketchat.md b/docs/commands/lagoon_update_rocketchat.md deleted file mode 100644 index bedbd37f..00000000 --- a/docs/commands/lagoon_update_rocketchat.md +++ /dev/null @@ -1,44 +0,0 @@ -## lagoon update rocketchat - -Update an existing Rocket.Chat notification - -### Synopsis - -Update an existing Rocket.Chat notification - -``` -lagoon update rocketchat [flags] -``` - -### Options - -``` - -c, --channel string The channel for the notification - -h, --help help for rocketchat - -j, --json string JSON string to patch - -n, --name string The current name of the notification - -N, --newname string The name of the notification - -w, --webhook string The webhook URL of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon update](lagoon_update.md) - Update a resource - diff --git a/docs/commands/lagoon_update_slack.md b/docs/commands/lagoon_update_slack.md deleted file mode 100644 index c242d822..00000000 --- a/docs/commands/lagoon_update_slack.md +++ /dev/null @@ -1,44 +0,0 @@ -## lagoon update slack - -Update an existing Slack notification - -### Synopsis - -Update an existing Slack notification - -``` -lagoon update slack [flags] -``` - -### Options - -``` - -c, --channel string The channel for the notification - -h, --help help for slack - -j, --json string JSON string to patch - -n, --name string The current name of the notification - -N, --newname string The name of the notification - -w, --webhook string The webhook URL of the notification -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon update](lagoon_update.md) - Update a resource - diff --git a/docs/commands/lagoon_web.md b/docs/commands/lagoon_web.md deleted file mode 100644 index cb9edd92..00000000 --- a/docs/commands/lagoon_web.md +++ /dev/null @@ -1,38 +0,0 @@ -## lagoon web - -Launch the web user interface - -``` -lagoon web [flags] -``` - -### Options - -``` - -h, --help help for web -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication - --ssh-publickey string Specify path to a specific SSH public key to use for lagoon authentication using ssh-agent. - This will override any public key identities defined in configuration - -v, --verbose Enable verbose output to stderr (if supported) -``` - -### SEE ALSO - -* [lagoon](lagoon.md) - Command line integration for Lagoon - diff --git a/docs/config.md b/docs/config.md index 321b027b..4279185b 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,95 +1,71 @@ # Introduction -By default the CLI is configured to use the `amazeeio` Lagoon. But you can also define additional Lagoons if you need to. - -The `.lagoon.yml` file will be installed in your home directory by default - -## Layout of the configuration file -The configuration file is laid out like below -```yaml -current: amazeeio -default: amazeeio -lagoons: - amazeeio: - graphql: https://api.lagoon.amazeeio.cloud/graphql - hostname: ssh.lagoon.amazeeio.cloud - port: 32222 - token: ey.....xA -``` -There are a few sections to cover off - -* `current` is the current Lagoon that you will be using, if you only have the one, it will be `amazeeio` -* `default` is the default Lagoon to use, if you always use a particular Lagoon then you can set your preference as your default -* `lagoons` is where the actual connection parameters are stored for each Lagoon, they all follow the same template. - * `graphql` is the graphql endpoint - * `hostname` is the ssh hostname - * `port` is the ssh port - * `token` is the graphql token, this is automatically generate the first time you `lagoon login` and will automatically refresh if it expires via ssh. - -# Add a Lagoon -If you want to add a different Lagoon to use, then you can use the CLI command to view the flags available -```bash -lagoon config add --lagoon LagoonName -``` -## Example -```bash -lagoon config add --lagoon amazeeio \ - --graphql https://api.lagoon.amazeeio.cloud/graphql \ - --hostname ssh.lagoon.amazeeio.cloud \ - --port 32222 -``` +Lagoon CLI uses a shared configuration package. You can [read more about it here](https://github.com/uselagoon/machinery/tree/main/utils/config). -# Delete a Lagoon -If you want to remove a Lagoon, you can use -```bash -lagoon config delete --lagoon LagoonName -``` -## Example -```bash -lagoon config delete --lagoon amazeeio -``` +It uses [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) for storing the configuration in known locations. -# Change default Lagoon -If you add additional Lagoons, you can select which one is the default you want to use by running -```bash -lagoon config default --lagoon LagoonName -``` -## Example -```bash -lagoon config default --lagoon amazeeio -``` +The main configuration file will be stored in `$XDG_CONFIG_HOME` with the file location being in a `lagoon` directory, with the actual configuration file being named `config.yaml`. -# Use a different Lagoon -If you want to temporarily use a different Lagoon, when you run any commands you can specify the flag `--lagoon` or `-l` and then the name of the Lagoon -## Example -```bash -lagoon --lagoon mylagoon list projects -``` +The full path will then be `$XDG_CONFIG_HOME/lagoon/config.yml`. + +If `$XDG_CONFIG_HOME` is not set, then depending on the operating system, this location could be different. Review the specification to understand more about this. + +# Usage + +See the sub command `lagoon configuration` for information on managing users and contexts. + +# Components + +Configuration is broken down into two core components, `users` and `contexts`. You need a user, and you need a context, a user must be linked to a context. + +Information about the two components are below, but further information can be found in the package that defines configurations if you want further information. + +## Users + +Users are a way to leverage separate SSH keys if using SSH based authentication. This user does not have to match the name of an account within the Lagoon, but a friendly name for the conifugration owner. + +## Contexts + +Contexts are a way to leverage multiple Lagoons. A context needs a user linked to it, you can change the user associated to a context, and you can define multiple contexts for the same cluster with different users. -# View Lagoons -You can view all the Lagoons you have configured by running -```bash -lagoon config list +## Features + +The Lagoon CLI has some features that can be enabled and disabled. Features may be disabled by default, depending on the feature or features name. Features can be defined globally, or for a specific context if required. + +See the help output of `lagoon configuration feature` for how to change features. + +### ssh-token + +This feature when set to `true` will only use SSH to get a token, instead of using the Lagoon provided Keycloak OAuth mechanism. This is useful if you're using the CLI and are unable to use the OAuth mechanism to authenticate with the API for any reason, for example in a CI job. + +The default value of this is `false` (or unset). + +### disable-update-check + +This feature when set to `true` will inform the CLI to not perform the automatic update checks. + +The default value of this is `false` (or unset). + +### environment-from-directory + +This feature when set to `true` will enable the abilty for the CLI to read some basic information from the directory the command is executed in to try and guess which project or environment you're in. + +> Note: The recommendation is to never use this feature. We may deprecate this feature in the future. + +The default value of this is `false` (or unset). + +# Migrating from the legacy configuration + +Previous versions of Lagoon CLI used a `.lagoon.yml` in a home directory. This is no longer the case. + +The CLI offers a way to convert a legacy configuration into the new format. It will not modify the legacy configuration though, only read it. + +You can run it in dry run mode first to see what the resulting configuration will prompt you to provide input for. ``` -Output -```yaml -You have the following lagoons configured: -Name: amazeeio - - Hostname: ssh.lagoon.amazeeio.cloud - - GraphQL: https://api.lagoon.amazeeio.cloud/graphql - - Port: 32222 -Name: mylagoon - - Hostname: ssh.mylagoon.example - - GraphQL: https://api.mylagoon.example/graphql - - Port: 32000 -Name: local - - Hostname: localhost - - GraphQL: http://localhost:3000/graphql - - Port: 2020 - -Your default lagoon is: -Name: local - -Your current lagoon is: -Name: local +lagoon configuration convert-config +``` + +If you're happy with the process, and the output looks good, you can run it again with the `--write-config` flag (you will be prompted for input again). ``` +lagoon configuration convert-config --write-config +``` \ No newline at end of file diff --git a/go.mod b/go.mod index 08505142..575b37a2 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.21 require ( github.com/Masterminds/semver/v3 v3.2.1 + github.com/adrg/xdg v0.4.0 github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang/mock v1.6.0 github.com/google/go-github v0.0.0-20180716180158-c0b63e2f9bb1 @@ -15,12 +16,12 @@ require ( github.com/logrusorgru/aurora v2.0.3+incompatible github.com/machinebox/graphql v0.2.3-0.20181106130121-3a9253180225 github.com/manifoldco/promptui v0.9.0 - github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.2 github.com/uselagoon/machinery v0.0.24 golang.org/x/crypto v0.21.0 + golang.org/x/oauth2 v0.17.0 golang.org/x/term v0.18.0 gopkg.in/yaml.v3 v3.0.1 sigs.k8s.io/yaml v1.4.0 @@ -30,6 +31,7 @@ require ( github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect @@ -37,7 +39,10 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + golang.org/x/net v0.21.0 // indirect golang.org/x/sys v0.18.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.31.0 // indirect ) //replace github.com/uselagoon/machinery => ../machinery diff --git a/go.sum b/go.sum index cf04cbec..79ed6910 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= +github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= @@ -15,6 +17,11 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v0.0.0-20180716180158-c0b63e2f9bb1 h1:tV3a8xSFYfQgA9b54eOE0A6Db//aeD+SQWawHfhaoLs= @@ -43,8 +50,6 @@ github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98= -github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= @@ -61,6 +66,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -75,8 +81,13 @@ golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -85,6 +96,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -92,13 +104,21 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/lagoon/config.go b/internal/lagoon/config.go index 60e76a06..15c44c39 100644 --- a/internal/lagoon/config.go +++ b/internal/lagoon/config.go @@ -1,5 +1,20 @@ package lagoon +/* + + _ _ _ + | | | | | | + __| | ___ _ __ _ __ ___ ___ __ _| |_ ___ __| | + / _` |/ _ \ '_ \| '__/ _ \/ __/ _` | __/ _ \/ _` | +| (_| | __/ |_) | | | __/ (_| (_| | || __/ (_| | + \__,_|\___| .__/|_| \___|\___\__,_|\__\___|\__,_| + | | + |_| + +this configuration has being replaced with github.com/uselagoon/machinery/utils/config + +*/ + // Config is used for the lagoon configuration. type Config struct { Current string `json:"current"`