Skip to content

Commit

Permalink
fixes secrets queries and intros sync command
Browse files Browse the repository at this point in the history
  • Loading branch information
mhausenblas committed Jul 20, 2019
1 parent f53ff5d commit e9db2bd
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 10 deletions.
8 changes: 7 additions & 1 deletion access-graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ func NewAccessGraph(cfg aws.Config) *AccessGraph {
if err != nil {
fmt.Printf("Can't get Kubernetes service accounts: %v", err.Error())
}
err = ag.kubeSecrets()
if err != nil {
fmt.Printf("Can't get Kubernetes secrets: %v", err.Error())
}
return ag
}

Expand All @@ -78,12 +82,14 @@ func (ag *AccessGraph) String() string {
"EKS roles: %v\n"+
"EKS policies: %v\n"+
"Kube context: %+v\n"+
"Kube service accounts: %+v\n",
"Kube service accounts: %+v\n"+
"Kube secrets: %+v\n",
ag.User,
ag.Caller,
ag.Roles,
ag.Policies,
ag.KubeConfig.CurrentContext,
ag.ServiceAccounts,
ag.Secrets,
)
}
17 changes: 14 additions & 3 deletions interaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ import (
"github.com/c-bata/go-prompt"
)

// toplevel represents the top level choices in the interaction
// toplevel represents the top level choices in the interaction.
func toplevel(d prompt.Document) []prompt.Suggest {
s := []prompt.Suggest{
{Text: "iam-roles", Description: "Select an AWS IAM role to explore"},
{Text: "k8s-sa", Description: "Select an Kubernetes service accounts to explore"},
{Text: "k8s-secrets", Description: "Select a Kubernetes secret to explore"},
{Text: "sync", Description: "Synchronize the local state with IAM and Kubernetes"},
{Text: "help", Description: "Explain how it works and show available commands"},
{Text: "quit", Description: "Terminate the interactive session and quit"},
}
return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
}

// selectRole allows user to select an IAM role by ARN
// selectRole allows user to select an IAM role by ARN.
func selectRole(d prompt.Document) []prompt.Suggest {
s := []prompt.Suggest{}
for rolearn := range ag.Roles {
Expand All @@ -24,11 +26,20 @@ func selectRole(d prompt.Document) []prompt.Suggest {
return prompt.FilterContains(s, d.GetWordBeforeCursor(), true)
}

// selectSA allows user to select an Kubernetes service account
// selectSA allows user to select an Kubernetes service account.
func selectSA(d prompt.Document) []prompt.Suggest {
s := []prompt.Suggest{}
for saname := range ag.ServiceAccounts {
s = append(s, prompt.Suggest{Text: saname})
}
return prompt.FilterContains(s, d.GetWordBeforeCursor(), true)
}

// selectSecret allows user to select an Kubernetes secret.
func selectSecret(d prompt.Document) []prompt.Suggest {
s := []prompt.Suggest{}
for secname := range ag.Secrets {
s = append(s, prompt.Suggest{Text: secname})
}
return prompt.FilterContains(s, d.GetWordBeforeCursor(), true)
}
36 changes: 33 additions & 3 deletions k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (ag *AccessGraph) kubeIdentity() error {
return nil
}

// kubeServiceAccounts retrieve the service accounts in the cluster
// kubeServiceAccounts retrieve the service accounts in the cluster.
func (ag *AccessGraph) kubeServiceAccounts() error {
res, err := kubecuddler.Kubectl(false, false, "", "get", "sa", "--all-namespaces", "--output", "json")
if err != nil {
Expand All @@ -50,7 +50,7 @@ func (ag *AccessGraph) kubeServiceAccounts() error {
return nil
}

// format provides a textual rendering of the service account
// formatSA provides a textual rendering of the service account.
func formatSA(sa *ServiceAccount) string {
var secrets strings.Builder
for _, sec := range sa.Secrets {
Expand All @@ -66,7 +66,7 @@ func formatSA(sa *ServiceAccount) string {
)
}

// kubeSecrets retrieve the secrets in the cluster
// kubeSecrets retrieve the secrets in the cluster.
func (ag *AccessGraph) kubeSecrets() error {
res, err := kubecuddler.Kubectl(false, false, "", "get", "secrets", "--all-namespaces", "--output", "json")
if err != nil {
Expand All @@ -85,3 +85,33 @@ func (ag *AccessGraph) kubeSecrets() error {
}
return nil
}

// formatSecret provides a textual rendering of the secret.
func formatSecret(secret *Secret) string {
strdatamap := ""
// case of string data present:
if len(secret.StringData) != 0 {
for k, v := range secret.StringData {
strdatamap += fmt.Sprintf("%v: %v ", k, v)
}
}
datamap := ""
// case of data present:
if len(secret.Data) != 0 {
for k, v := range secret.Data {
datamap += fmt.Sprintf("\n %v: %v ", k, string(v))
}
}
return fmt.Sprintf(
" Namespace: %v\n"+
" Name: %v\n"+
" Type: %v\n"+
" String data: %v\n"+
" Data: %v\n",
secret.Namespace,
secret.Name,
secret.Type,
strdatamap,
datamap,
)
}
24 changes: 21 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ func main() {
cursel := "help" // make sure to first show the help to guide users what to do
for {
switch cursel {
case "sync":
fmt.Println("Gathering info from IAM and Kubernetes. This may take a bit, please stand by ...")
ag = NewAccessGraph(cfg)
case "iam-roles":
targetrole := prompt.Input(" ↪ ", selectRole)
if role, ok := ag.Roles[targetrole]; ok {
Expand All @@ -40,15 +43,22 @@ func main() {
if sa, ok := ag.ServiceAccounts[targetsa]; ok {
presult(formatSA(&sa))
}
case "k8s-secrets":
targetsec := prompt.Input(" ↪ ", selectSecret)
if secret, ok := ag.Secrets[targetsec]; ok {
presult(formatSecret(&secret))
}
case "help":
presult(fmt.Sprintf("\nThis is rbIAM in version %v\n\n", Version))
presult(strings.Repeat("-", 80))
presult("\nSelect one of the supported query commands:\n")
presult("- iam-roles … to look up an AWS IAM role by ARN\n")
presult("- k8s-sa … to look up an Kubernetes service account\n")
presult("- k8s-secrets … to look up a Kubernetes secret\n")
presult("- sync … to refresh the local data\n")
presult(strings.Repeat("-", 80))
presult("\n\nNote: simply start typing and/or use the tab and cursor keys to select.\n")
presult("CTRL+L clears the screen and if you're stuck type 'help'.\n\n")
presult("CTRL+L clears the screen and if you're stuck type 'help' or 'quit' to leave.\n\n")
case "quit":
presult("bye!\n")
os.Exit(0)
Expand All @@ -59,9 +69,17 @@ func main() {
}
}

// presult writes msg in blue to stdout. you need to take care of
// newlines yourself and for available colors see:
// Below some helper functions for output. For available colors see:
// https://misc.flogisoft.com/bash/tip_colors_and_formatting

// presult writes msg in blue to stdout and note that you need to take
// care of newlines yourself.
func presult(msg string) {
_, _ = fmt.Fprintf(os.Stdout, "\x1b[34m%v\x1b[0m", msg)
}

// pwarning writes msg in red to stdout and note that you need to take
// care of newlines yourself.
func pwarning(msg string) {
_, _ = fmt.Fprintf(os.Stdout, "\x1b[31m%v\x1b[0m", msg)
}

0 comments on commit e9db2bd

Please sign in to comment.