Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding option to specify an aws profile for auth #16767

Merged
merged 3 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assets/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -5664,6 +5664,10 @@
"type": "string",
"title": "ClusterName contains AWS cluster name"
},
"profile": {
"description": "Profile contains optional role ARN. If set then AWS IAM Authenticator uses the profile to perform cluster operations instead of the default AWS credential provider chain.",
"type": "string"
},
"roleARN": {
"description": "RoleARN contains optional role ARN. If set then AWS IAM Authenticator assume a role to perform cluster operations instead of the default AWS credential provider chain.",
"type": "string"
Expand Down
16 changes: 10 additions & 6 deletions cmd/argocd-k8s-auth/commands/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@ func newAWSCommand() *cobra.Command {
var (
clusterName string
roleARN string
profile string
)
var command = &cobra.Command{
Use: "aws",
Run: func(c *cobra.Command, args []string) {
ctx := c.Context()

presignedURLString, err := getSignedRequestWithRetry(ctx, time.Minute, 5*time.Second, clusterName, roleARN, getSignedRequest)
presignedURLString, err := getSignedRequestWithRetry(ctx, time.Minute, 5*time.Second, clusterName, roleARN, profile, getSignedRequest)
errors.CheckError(err)
token := v1Prefix + base64.RawURLEncoding.EncodeToString([]byte(presignedURLString))
// Set token expiration to 1 minute before the presigned URL expires for some cushion
Expand All @@ -53,16 +54,17 @@ func newAWSCommand() *cobra.Command {
}
command.Flags().StringVar(&clusterName, "cluster-name", "", "AWS Cluster name")
command.Flags().StringVar(&roleARN, "role-arn", "", "AWS Role ARN")
command.Flags().StringVar(&profile, "profile", "", "AWS Profile")
return command
}

type getSignedRequestFunc func(clusterName, roleARN string) (string, error)
type getSignedRequestFunc func(clusterName, roleARN string, profile string) (string, error)

func getSignedRequestWithRetry(ctx context.Context, timeout, interval time.Duration, clusterName, roleARN string, fn getSignedRequestFunc) (string, error) {
func getSignedRequestWithRetry(ctx context.Context, timeout, interval time.Duration, clusterName, roleARN string, profile string, fn getSignedRequestFunc) (string, error) {
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
for {
signed, err := fn(clusterName, roleARN)
signed, err := fn(clusterName, roleARN, profile)
if err == nil {
return signed, nil
}
Expand All @@ -74,8 +76,10 @@ func getSignedRequestWithRetry(ctx context.Context, timeout, interval time.Durat
}
}

func getSignedRequest(clusterName, roleARN string) (string, error) {
sess, err := session.NewSession()
func getSignedRequest(clusterName, roleARN string, profile string) (string, error) {
sess, err := session.NewSessionWithOptions(session.Options{
Profile: profile,
})
if err != nil {
return "", fmt.Errorf("error creating new AWS session: %s", err)
}
Expand Down
8 changes: 4 additions & 4 deletions cmd/argocd-k8s-auth/commands/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestGetSignedRequestWithRetry(t *testing.T) {
}

// when
signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", mock.getSignedRequestMock)
signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", "", mock.getSignedRequestMock)

// then
assert.NoError(t, err)
Expand All @@ -41,7 +41,7 @@ func TestGetSignedRequestWithRetry(t *testing.T) {
}

// when
signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", mock.getSignedRequestMock)
signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", "", mock.getSignedRequestMock)

// then
assert.NoError(t, err)
Expand All @@ -57,7 +57,7 @@ func TestGetSignedRequestWithRetry(t *testing.T) {
}

// when
signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", mock.getSignedRequestMock)
signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", "", mock.getSignedRequestMock)

// then
assert.Error(t, err)
Expand All @@ -70,7 +70,7 @@ type signedRequestMock struct {
returnFunc func(m *signedRequestMock) (string, error)
}

func (m *signedRequestMock) getSignedRequestMock(clusterName, roleARN string) (string, error) {
func (m *signedRequestMock) getSignedRequestMock(clusterName, roleARN string, profile string) (string, error) {
m.getSignedRequestCalls++
return m.returnFunc(m)
}
1 change: 1 addition & 0 deletions cmd/argocd/commands/admin/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command
awsAuthConf = &argoappv1.AWSAuthConfig{
ClusterName: clusterOpts.AwsClusterName,
RoleARN: clusterOpts.AwsRoleArn,
Profile: clusterOpts.AwsProfile,
}
} else if clusterOpts.ExecProviderCommand != "" {
execProviderConf = &argoappv1.ExecProviderConfig{
Expand Down
1 change: 1 addition & 0 deletions cmd/argocd/commands/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie
awsAuthConf = &argoappv1.AWSAuthConfig{
ClusterName: clusterOpts.AwsClusterName,
RoleARN: clusterOpts.AwsRoleArn,
Profile: clusterOpts.AwsProfile,
}
} else if clusterOpts.ExecProviderCommand != "" {
execProviderConf = &argoappv1.ExecProviderConfig{
Expand Down
2 changes: 2 additions & 0 deletions cmd/util/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ type ClusterOptions struct {
Upsert bool
ServiceAccount string
AwsRoleArn string
AwsProfile string
AwsClusterName string
SystemNamespace string
Namespaces []string
Expand All @@ -169,6 +170,7 @@ func AddClusterFlags(command *cobra.Command, opts *ClusterOptions) {
command.Flags().BoolVar(&opts.InCluster, "in-cluster", false, "Indicates Argo CD resides inside this cluster and should connect using the internal k8s hostname (kubernetes.default.svc)")
command.Flags().StringVar(&opts.AwsClusterName, "aws-cluster-name", "", "AWS Cluster name if set then aws cli eks token command will be used to access cluster")
command.Flags().StringVar(&opts.AwsRoleArn, "aws-role-arn", "", "Optional AWS role arn. If set then AWS IAM Authenticator assumes a role to perform cluster operations instead of the default AWS credential provider chain.")
command.Flags().StringVar(&opts.AwsProfile, "aws-profile", "", "Optional AWS profile. If set then AWS IAM Authenticator uses this profile to perform cluster operations instead of the default AWS credential provider chain.")
command.Flags().StringArrayVar(&opts.Namespaces, "namespace", nil, "List of namespaces which are allowed to manage")
command.Flags().BoolVar(&opts.ClusterResources, "cluster-resources", false, "Indicates if cluster level resources should be managed. The setting is used only if list of managed namespaces is not empty.")
command.Flags().StringVar(&opts.Name, "name", "", "Overwrite the cluster name")
Expand Down
1 change: 1 addition & 0 deletions docs/operator-manual/declarative-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ bearerToken: string
awsAuthConfig:
clusterName: string
roleARN: string
profile: string
# Configure external command to supply client credentials
# See https://godoc.org/k8s.io/client-go/tools/clientcmd/api#ExecConfig
execProviderConfig:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ argocd admin cluster generate-spec CONTEXT [flags]
```
--annotation stringArray Set metadata annotations (e.g. --annotation key=value)
--aws-cluster-name string AWS Cluster name if set then aws cli eks token command will be used to access cluster
--aws-profile string Optional AWS profile. If set then AWS IAM Authenticator uses this profile to perform cluster operations instead of the default AWS credential provider chain.
--aws-role-arn string Optional AWS role arn. If set then AWS IAM Authenticator assumes a role to perform cluster operations instead of the default AWS credential provider chain.
--bearer-token string Authentication token that should be used to access K8S API server
--cluster-endpoint string Cluster endpoint to use. Can be one of the following: 'kubeconfig', 'kube-public', or 'internal'.
Expand Down
1 change: 1 addition & 0 deletions docs/user-guide/commands/argocd_cluster_add.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ argocd cluster add CONTEXT [flags]
```
--annotation stringArray Set metadata annotations (e.g. --annotation key=value)
--aws-cluster-name string AWS Cluster name if set then aws cli eks token command will be used to access cluster
--aws-profile string Optional AWS profile. If set then AWS IAM Authenticator uses this profile to perform cluster operations instead of the default AWS credential provider chain.
--aws-role-arn string Optional AWS role arn. If set then AWS IAM Authenticator assumes a role to perform cluster operations instead of the default AWS credential provider chain.
--cluster-endpoint string Cluster endpoint to use. Can be one of the following: 'kubeconfig', 'kube-public', or 'internal'.
--cluster-resources Indicates if cluster level resources should be managed. The setting is used only if list of managed namespaces is not empty.
Expand Down
Loading
Loading