Skip to content

Commit

Permalink
add new subcommand: auth whoami
Browse files Browse the repository at this point in the history
  • Loading branch information
mozillazg committed Sep 26, 2024
1 parent 3cd5810 commit 062c207
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 20 deletions.
2 changes: 2 additions & 0 deletions cmd/ack-ram-tool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider"
"github.com/AliyunContainerService/ack-ram-tool/pkg/ctl"
"github.com/AliyunContainerService/ack-ram-tool/pkg/ctl/auth"
"github.com/AliyunContainerService/ack-ram-tool/pkg/ctl/credentialplugin"
"github.com/AliyunContainerService/ack-ram-tool/pkg/ctl/exportcredentials"
"github.com/AliyunContainerService/ack-ram-tool/pkg/ctl/rbac"
Expand Down Expand Up @@ -44,6 +45,7 @@ func init() {
version.SetupVersionCmd(rootCmd)
rbac.SetupCmd(rootCmd)
exportcredentials.SetupCmd(rootCmd)
auth.SetupCmd(rootCmd)

rootCmd.PersistentFlags().StringVar(&ctl.GlobalOption.Region, "region-id",
"", "The region to use"+
Expand Down
19 changes: 19 additions & 0 deletions pkg/ctl/auth/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package auth

import (
"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
Use: "auth",
Short: "Utils for auth.",
Long: `Utils for auth.`,
}

func init() {
setupWhoamiCmdCmd(rootCmd)
}

func SetupCmd(root *cobra.Command) {
root.AddCommand(rootCmd)
}
58 changes: 58 additions & 0 deletions pkg/ctl/auth/whoami.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package auth

import (
"context"
"github.com/AliyunContainerService/ack-ram-tool/pkg/ctl"
"github.com/AliyunContainerService/ack-ram-tool/pkg/ctl/common"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
"os"
)

var whoamiCmd = &cobra.Command{
Use: "whoami",
Short: "Check who you are",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
ctl.GlobalOption.Verbose = true
client := common.GetClientOrDie()

acc, err := client.GetCallerIdentity(context.TODO())
common.ExitIfError(err)
table := tablewriter.NewWriter(os.Stdout)
//table.SetAutoMergeCells(true)
table.SetAutoWrapText(true)
table.SetAutoFormatHeaders(false)
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetCenterSeparator("")
table.SetColumnSeparator("")
table.SetRowSeparator("")
table.SetHeaderLine(false)
table.EnableBorder(false)
table.SetTablePadding(" ")
table.SetNoWhiteSpace(true)

table.Append([]string{"AccountId", acc.RootUId})
table.Append([]string{"IdentityType", acc.IdentityType()})
if acc.Role.RoleId != "" {
table.Append([]string{"RoleId", acc.Role.RoleId})
table.Append([]string{"RoleName", acc.Role.RoleName})
} else if acc.User.Id != "" {
table.Append([]string{"UserId", acc.User.Id})
table.Append([]string{"UserName", acc.User.Name})
}
table.Append([]string{"Arn", acc.Arn})
table.Append([]string{"PrincipalId", acc.PrincipalId})

table.Render()
},
}

func setupWhoamiCmdCmd(rootCmd *cobra.Command) {
rootCmd.AddCommand(whoamiCmd)

whoamiCmd.Flags().StringVar(
&ctl.GlobalOption.FinalAssumeRoleAnotherRoleArn, "role-arn", "",
"Assume an RAM Role ARN when send request or sign token")
}
33 changes: 23 additions & 10 deletions pkg/ctl/common/client.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package common

import (
"context"
"fmt"
"os"

"github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudgo"
"github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudgo/env"
"github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/credentialsgov13"
"github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider"
Expand Down Expand Up @@ -92,22 +92,32 @@ func getCredential(opt getCredentialOption) (provider.CredentialsProvider, error
ignoreAliyuncli := opt.ignoreAliyuncli
aliyuncliProfileName := opt.aliyuncliProfileName

// env
if credentialFilePath == "" && aliyuncliConfigFilePath == "" {
if sessionName != "" {
_ = os.Setenv(env.EnvRoleSessionName, sessionName)
}
if !ignoreEnv {
log.Logger.Debug("try to get credentials from environment variables")
// TODO: support ecs ALIBABA_CLOUD_ECS_METADATA
if cred, err := env.NewCredentialsProvider(env.CredentialsProviderOptions{
cred, _ := env.NewCredentialsProvider(env.CredentialsProviderOptions{

Check failure on line 103 in pkg/ctl/common/client.go

View workflow job for this annotation

GitHub Actions / lint

SA4023(related information): the lhs of the comparison is the 1st return value of this function call (staticcheck)
STSEndpoint: opt.stsEndpoint,
}); err == nil && cred != nil {
log.Logger.Debugf("use credentials from environment variables")
return cred, err
})
if cred != nil {

Check failure on line 106 in pkg/ctl/common/client.go

View workflow job for this annotation

GitHub Actions / lint

SA4023: this comparison is always true (staticcheck)
_, err := cred.Credentials(context.TODO())
if err == nil || !provider.IsNotEnableError(err) {
log.Logger.Debugf("use credentials from environment variables")
return cred, nil
} else {
log.Logger.Debugf("get credentials from environment variables failed: %+v, try another method",
err)
}
}
log.Logger.Debug("not found credentials from environment variables")
}
}

// aliyun cli config
if aliyuncliConfigFilePath == "" {
aliyuncliConfigFilePath, _ = utils.ExpandPath("~/.aliyun/config.json")
if path, err := checkFileExist(aliyuncliConfigFilePath); err != nil && os.IsNotExist(err) {
Expand All @@ -117,7 +127,6 @@ func getCredential(opt getCredentialOption) (provider.CredentialsProvider, error
aliyuncliConfigFilePath = path
}
}

if !ignoreAliyuncli {
if path, err := checkFileExist(aliyuncliConfigFilePath); err != nil {
return nil, fmt.Errorf("read file %s: %w", aliyuncliConfigFilePath, err)
Expand All @@ -144,6 +153,7 @@ func getCredential(opt getCredentialOption) (provider.CredentialsProvider, error
}
}

// ini config
if credentialFilePath == "" {
path, err := checkFileExist(credentials.PATHCredentialFile)
if err != nil && os.IsNotExist(err) {
Expand All @@ -153,19 +163,22 @@ func getCredential(opt getCredentialOption) (provider.CredentialsProvider, error
credentialFilePath = path
}

log.Logger.Debugf("get default credentials from %s", utils.ShortHomePath(credentialFilePath))
log.Logger.Debugf("try to get default credentials from %s", utils.ShortHomePath(credentialFilePath))
if path, err := checkFileExist(credentialFilePath); err != nil {
return nil, fmt.Errorf("read file %s: %w", credentialFilePath, err)
} else {
credentialFilePath = path
}

_ = os.Setenv(credentials.ENVCredentialFile, credentialFilePath)
cred, err := credentials.NewCredential(nil)
cred, err := provider.NewIniConfigProvider(provider.INIConfigProviderOptions{
ConfigPath: credentialFilePath,
STSEndpoint: opt.stsEndpoint,
Logger: log.ProviderLogger(),
})
if err != nil {
return nil, err
}
return alibabacloudgo.NewCredentialsProviderWrapper(cred), nil
return cred, nil
}

func GetClientOrDie() *openapi.Client {
Expand Down
44 changes: 35 additions & 9 deletions pkg/openapi/sts.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"github.com/AliyunContainerService/ack-ram-tool/pkg/types"
"github.com/alibabacloud-go/tea/tea"
"strings"
"time"

"github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/oidctoken"
Expand Down Expand Up @@ -42,33 +43,58 @@ func (c *Client) GetCallerIdentity(ctx context.Context) (*types.Account, error)
return nil, fmt.Errorf("unkown resp: %s", resp.String())
}
body := resp.Body
arn := getRealArn(tea.StringValue(body.Arn))
switch tea.StringValue(body.IdentityType) {
case "Account":
return &types.Account{
Type: types.AccountTypeRoot,
RootUId: tea.StringValue(body.AccountId),
PrincipalId: tea.StringValue(body.PrincipalId),
Arn: arn,
Type: types.AccountTypeRoot,
RootUId: tea.StringValue(body.AccountId),
User: types.RamUser{
Id: tea.StringValue(body.UserId),
},
}, nil
case "RAMUser":
parts := strings.Split(arn, "/")
name := parts[len(parts)-1]
return &types.Account{
Type: types.AccountTypeUser,
RootUId: tea.StringValue(body.AccountId),
PrincipalId: tea.StringValue(body.PrincipalId),
Arn: arn,
Type: types.AccountTypeUser,
RootUId: tea.StringValue(body.AccountId),
User: types.RamUser{
Id: tea.StringValue(body.UserId),
Id: tea.StringValue(body.UserId),
Name: name,
},
}, nil
case "AssumedRoleUser":
parts := strings.Split(arn, "/")
name := parts[len(parts)-1]
return &types.Account{
Type: types.AccountTypeRole,
RootUId: tea.StringValue(body.AccountId),
PrincipalId: tea.StringValue(body.PrincipalId),
Arn: arn,
Type: types.AccountTypeRole,
RootUId: tea.StringValue(body.AccountId),
Role: types.RamRole{
RoleId: tea.StringValue(body.RoleId),
Arn: tea.StringValue(body.Arn),
RoleId: tea.StringValue(body.RoleId),
Arn: tea.StringValue(body.Arn),
RoleName: name,
},
}, nil
}

return nil, fmt.Errorf("unkown resp: %s", resp.String())
}

func getRealArn(raw string) string {
roleKey := ":assumed-role/"
arn := raw
if strings.Contains(raw, roleKey) {
arn = strings.Replace(arn, roleKey, ":role/", 1)
parts := strings.Split(arn, "/")
parts = parts[:len(parts)-1]
arn = strings.Join(parts, "/")
}
return arn
}
15 changes: 15 additions & 0 deletions pkg/types/ram.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ type Account struct {
RootUId string
User RamUser
Role RamRole

PrincipalId string
Arn string
}

type RamRole struct {
Expand Down Expand Up @@ -267,6 +270,18 @@ func NewFakeAccount(uid int64) Account {
return acc
}

func (a *Account) IdentityType() string {
switch a.Type {
case AccountTypeRoot:
return "Account"
case AccountTypeUser:
return "RAMUser"
case AccountTypeRole:
return "AssumedRoleUser"
}
return ""
}

func (a *Account) MarkDeleted() {
switch a.Type {
case AccountTypeUser:
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 062c207

Please sign in to comment.