From e08ee3cf028af37739b0e8d367d97edbf902a9e6 Mon Sep 17 00:00:00 2001 From: Jay Dhulia <46459060+jaydhulia@users.noreply.github.com> Date: Thu, 16 Dec 2021 16:04:30 -0700 Subject: [PATCH] Wrapper for export (#110) * Wrapper for export * PR update * Legacy commands --- cmd/export.go | 33 +++++++++++++++++---- cmd/legacy.go | 32 ++++++++++++++++++++ cmd/legacy_export.go | 70 ++++++++++++++++++++++++++++++++++++++++++++ cmd/vars.go | 2 ++ pkg/util/util.go | 9 ++++++ 5 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 cmd/legacy.go create mode 100644 cmd/legacy_export.go diff --git a/cmd/export.go b/cmd/export.go index 09413df..875488f 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -57,7 +57,12 @@ func runExport(cmd *cobra.Command, args []string) error { logging.LogError(err, "Error getting credentials") return err } - printExport(credentials) + if !useShellFlag { + // user hasn't explicitly passed in a shell + printExport(credentials) + } else { + printExportForShell(shellInfo, credentials) + } return nil } @@ -72,13 +77,31 @@ func isFish() bool { } } +// User hasn't specified a shell, attempt to guess it func printExport(creds *aws.Credentials) { if isFish() { // fish has a different way of setting variables than bash/zsh and others - fmt.Printf("set -x AWS_ACCESS_KEY_ID %s && set -x AWS_SECRET_ACCESS_KEY %s && set -x AWS_SESSION_TOKEN %s\n", - creds.AccessKeyId, creds.SecretAccessKey, creds.SessionToken) + printExportForShell("fish", creds) } else { - fmt.Printf("export AWS_ACCESS_KEY_ID=%s && export AWS_SECRET_ACCESS_KEY=%s && export AWS_SESSION_TOKEN=%s\n", - creds.AccessKeyId, creds.SecretAccessKey, creds.SessionToken) + // defaults to bash + printExportForShell("bash", creds) + } +} + +// Prints out the export command for a specific shell, as defined by user +func printExportForShell(shell string, creds *aws.Credentials) { + fmt.Println(exportVar(shell, "AWS_ACCESS_KEY_ID", creds.AccessKeyId)) + fmt.Println(exportVar(shell, "AWS_SECRET_ACCESS_KEY", creds.SecretAccessKey)) + fmt.Println(exportVar(shell, "AWS_SESSION_TOKEN", creds.SessionToken)) +} + +func exportVar(shell, name, value string) string { + switch shell { + case "fish": + return fmt.Sprintf("set -gx %s %q;", name, value) + case "csh", "tcsh": + return fmt.Sprintf("setenv %s %q;", name, value) + default: // "sh", "bash", "ksh", "zsh": + return fmt.Sprintf("export %s=%q", name, value) } } diff --git a/cmd/legacy.go b/cmd/legacy.go new file mode 100644 index 0000000..6503c46 --- /dev/null +++ b/cmd/legacy.go @@ -0,0 +1,32 @@ +/* + * Copyright 2020 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(legacyCmd) +} + +// legacyCmd to allow for backwards-compatibility for legacy commands that implement the functionality currently +var legacyCmd = &cobra.Command{ + Use: "legacy [export]", + Short: "Legacy commands for backwards-compatibility", + Hidden: true, +} diff --git a/cmd/legacy_export.go b/cmd/legacy_export.go new file mode 100644 index 0000000..0a9b643 --- /dev/null +++ b/cmd/legacy_export.go @@ -0,0 +1,70 @@ +/* + * Copyright 2020 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "fmt" + + "github.com/netflix/weep/pkg/util" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +func init() { + legacyExportCmd.PersistentFlags().StringVarP(&roleRefreshARN, "role", "z", "", "role") + legacyExportCmd.PersistentFlags().StringVar(&shellInfo, "shell", "bash", "--shell=sh|bash|ksh|zsh|fish|csh|tcsh") + legacyCmd.AddCommand(legacyExportCmd) +} + +// wrapper to allow for backwards-compatibility for commands that implement the export functionality currently +var legacyExportCmd = &cobra.Command{ + Use: "export [profile]", + Short: exportShortHelp, + Hidden: true, + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) > 0 { + profileName = args[0] + } else { + profileName = "default" + } + + if roleRefreshARN == "" { + // roleRefreshARN is not present, have to go through aws-profiles to see if a role matches + awsProfiles := viper.GetStringMapString("aws-profiles") + for name, role := range awsProfiles { + if name == profileName { + roleRefreshARN = role + break + } + } + } + if roleRefreshARN == "" { + return fmt.Errorf("unable to find profile %s in 'aws-profiles' property. You can also run with -r role_name ", profileName) + } + + argsPass := []string{roleRefreshARN} + // explicit shell flag, rather than guessing which shell to use + useShellFlag = true + shells := []string{"sh", "bash", "ksh", "zsh", "fish", "csh", "tcsh"} + if !util.StringInSlice(shellInfo, shells) { + return fmt.Errorf("shell must be one of %s", shells) + } + return exportCmd.RunE(exportCmd, argsPass) + }, +} diff --git a/cmd/vars.go b/cmd/vars.go index 14b5201..08af6a0 100644 --- a/cmd/vars.go +++ b/cmd/vars.go @@ -42,11 +42,13 @@ var ( profileName string region string roleRefreshARN string + shellInfo string shortInfo bool showAll bool showConfiguredProfilesOnly bool showInstanceProfilesOnly bool shutdown chan os.Signal + useShellFlag bool ) var completionShortHelp = "Generate completion script" diff --git a/pkg/util/util.go b/pkg/util/util.go index 9a86212..4e83b0d 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -206,3 +206,12 @@ func RenderTabularData(headers []string, data [][]string) string { table.Render() return tableString.String() } + +func StringInSlice(elem string, list []string) bool { + for _, elemInList := range list { + if elem == elemInList { + return true + } + } + return false +}