Skip to content

Commit

Permalink
Feature: Interactive Role Finder (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
nsiow authored Aug 28, 2021
1 parent 268014d commit 5ef5b4a
Show file tree
Hide file tree
Showing 5 changed files with 447 additions and 110 deletions.
9 changes: 7 additions & 2 deletions cmd/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,17 @@ var exportCmd = &cobra.Command{
Use: "export [role_name]",
Short: exportShortHelp,
Long: exportLongHelp,
Args: cobra.ExactArgs(1),
Args: cobra.MaximumNArgs(1),
RunE: runExport,
}

func runExport(cmd *cobra.Command, args []string) error {
role := args[0]
// If a role was provided, use it, otherwise prompt
role, err := InteractiveRolePrompt(args, region, nil)
if err != nil {
return err
}

creds, err := creds.GetCredentials(role, noIpRestrict, assumeRole, "")
if err != nil {
return err
Expand Down
11 changes: 8 additions & 3 deletions cmd/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,18 @@ var fileCmd = &cobra.Command{
Use: "file [role_name]",
Short: fileShortHelp,
Long: fileLongHelp,
Args: cobra.ExactArgs(1),
Args: cobra.MaximumNArgs(1),
RunE: runFile,
}

func runFile(cmd *cobra.Command, args []string) error {
role := args[0]
err := updateCredentialsFile(role, profileName, destination, noIpRestrict, assumeRole)
// If a role was provided, use it, otherwise prompt
role, err := InteractiveRolePrompt(args, region, nil)
if err != nil {
return err
}

err = updateCredentialsFile(role, profileName, destination, noIpRestrict, assumeRole)
if err != nil {
return err
}
Expand Down
83 changes: 83 additions & 0 deletions cmd/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* 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"
"os"
"strings"

"github.com/lithammer/fuzzysearch/fuzzy"
"github.com/manifoldco/promptui"
"github.com/netflix/weep/pkg/creds"
)

// InteractiveRolePrompt will present the user with a fuzzy-searchable list of roles if
// - We are currently attached to an interactive tty
// - The user has not disabled them through the WEEP_DISABLE_INTERACTIVE_PROMPTS option
func InteractiveRolePrompt(args []string, region string, client *creds.Client) (string, error) {
// If a role was provided, just use that
if len(args) > 0 {
return args[0], nil
}

if !isRunningInTerminal() {
return "", fmt.Errorf("no role provided, and cannot prompt for input")
}

if os.Getenv("WEEP_DISABLE_INTERACTIVE_PROMPTS") == "1" {
return "", fmt.Errorf("no role provided, and interactive prompts are disabled")
}

// If a client was not provided, create one using the provided region
if client == nil {
var err error
client, err = creds.GetClient(region)
if err != nil {
return "", err
}
}

// Retrieve the list of roles
roles, err := client.Roles()
if err != nil {
return "", err
}

// Prompt the user
prompt := promptui.Select{
Label: "Select Role",
Items: roles,
Size: 16,
Searcher: func(input string, index int) bool {
return fuzzy.MatchNormalized(strings.ToLower(input), strings.ToLower(roles[index]))
},
StartInSearchMode: true,
}

_, role, err := prompt.Run()
if err != nil {
return "", err
}

return role, nil
}

func isRunningInTerminal() bool {
fileInfo, _ := os.Stdout.Stat()
return (fileInfo.Mode() & os.ModeCharDevice) != 0
}
16 changes: 3 additions & 13 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,17 @@ require (
github.com/golang/glog v0.0.0-20210429001901-424d2337a529
github.com/gorilla/mux v1.8.0
github.com/kardianos/service v1.2.0
github.com/kr/pretty v0.2.0 // indirect
github.com/lithammer/fuzzysearch v1.1.2
github.com/lunixbochs/vtclean v1.0.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/manifoldco/promptui v0.8.0
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/pelletier/go-toml v1.9.2 // indirect
github.com/pkg/errors v0.9.1
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sirupsen/logrus v1.8.1
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/cobra v1.1.3
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.5.1 // indirect
github.com/spf13/cobra v1.2.1
github.com/spf13/viper v1.8.1
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 // indirect
golang.org/x/text v0.3.6 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/ini.v1 v1.62.0
gopkg.in/yaml.v2 v2.4.0
)
Loading

0 comments on commit 5ef5b4a

Please sign in to comment.