-
Notifications
You must be signed in to change notification settings - Fork 296
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
HOSTEDCP-1561: Move HCP Product CLI to STS #4027
HOSTEDCP-1561: Move HCP Product CLI to STS #4027
Conversation
Skipping CI for Draft Pull Request. |
@Patryk-Stefanski: This pull request references HOSTEDCP-1561 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "4.16.0" version, but no target version was set. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
✅ Deploy Preview for hypershift-docs ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
cmd/infra/aws/create_cli_role.go
Outdated
) | ||
|
||
const ( | ||
cliRolePolicy = `{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't @muraee just add this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes he did, This PR wasn't meant to be reviewed yet (but I always welcome an early review :) ) and I was using his work for testing. So this comment and the following comments should have been left on his pr. In this case Im more than happy to make any changes that @muraee approves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. His PR already went in, let's get these following comments addressed in this PR then.
cmd/infra/aws/create_cli_role.go
Outdated
return nil | ||
} | ||
|
||
func assumeRoleTrustPolicy(ctx context.Context, client *sts.STS) (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it has a lot in common with iam.go
- let's refactor to share where we can, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as #4027 (comment)
cmd/infra/aws/create_cli_role.go
Outdated
return assumeRolePolicy, nil | ||
} | ||
|
||
func (o *CreateCLIRoleOptions) ParseAdditionalTags() ([]*iam.Tag, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a copy-pasta from iam.go
- please DRY it out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as #4027 (comment)
cmd/infra/aws/create_iam.go
Outdated
@@ -155,7 +169,17 @@ func (o *CreateIAMOptions) CreateIAM(ctx context.Context, client crclient.Client | |||
return nil, err | |||
} | |||
|
|||
awsSession := awsutil.NewSession("cli-create-iam", o.AWSCredentialsFile, o.AWSKey, o.AWSSecretKey, o.Region) | |||
var awsSession *session.Session |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sheer number of places where you need to add these new flags and validation is too high to be tenable. Let's break out some
type AWSCredentialOptions struct {
RoleARN string
STSCreds string
// whatever else
}
func DefaultOptions() *AWSCredentialOptions {
return &AWSCredentialOptions{/* place any meaningful defaults here */}
}
func BindOptions(opts *AWSCredentialOptions, flags *pflag.FlagSet) {
flags.StringVar(&opts.RoleArn, "role-arn", opts.RoleArn, "The ARN of the role to assume when creating the iam.")
flags.StringVar(&opts.StsCredentialsFile, "sts-creds", opts.StsCredentialsFile, "Path to STS credentials file to use when assuming the role.")
}
func (opts *AWSCredentialOptions) Validate() error {
/* add validation here */
}
Then, embed this struct into the others where needed and call BindOptions()
on it where flags are being added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as #4027 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stevekuznetsov because of the --secret-creds flag we sometimes need the roleArn without the need of stsCreds. I have created a new util validation function for validating the required flags here cmd/util/credentials_validation.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's find a factoring where we bind the flags once in the repo and validate them in one flow. If that means that the options need parameters on creation and/or validation, so be it. For all commands that want to authenticate to AWS, let's provide a package that lets them bind the flags they need and get an AWS session out the other end. A good litmus test IMHO will be that this PR adds only one line that binds sts-creds
as a flag to a struct member.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stevekuznetsov Just reading over the PR and I agree with you but since I'm leaving for PTO today and this feature is time sensitive I think this would be more of nice to have in this scenario. @muraee I don't know if you have the time to look into this approach or maybe this can be a separate Jira in our backlog?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't speak to timelines but I think trending in the direction I outline here will help us immensely with maintenance of the codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Patryk-Stefanski given that you'll be out, is it ok if we get someone else to take over the PR after today? I don't think @stevekuznetsov's are that big, but agree they would help with the maintenance of the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cmd/infra/aws/iam.go
Outdated
TrustPolicy string | ||
PermissionsPolicy string | ||
|
||
additionalIAMTags []*iam.Tag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this not exported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as #4027 (comment)
dce034f
to
01d10a4
Compare
bbad7cc
to
f54aca9
Compare
cmd/infra/aws/util/util.go
Outdated
} | ||
|
||
if credentialsFile != "" { | ||
stsSessionOpts.SharedConfigFiles = append(stsSessionOpts.SharedConfigFiles, credentialsFile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is expecting an aws credentials file, I think it should expect the output of aws sts get-session-token --output json
instead and then parse it and extract necessary fields.
Otherwise, the use will have to do 1 extra step to format the sts-creds file before passing it to the cli. If we do this, we can validate that the session_token exist and throw an error/warning that the user is not using temporary credentials.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some naming nits, otherwise lgtm
cmd/infra/aws/util/sts.go
Outdated
supportawsutil "github.com/openshift/hypershift/support/awsutil" | ||
) | ||
|
||
func NewStsSession(agent, rolenArn, region string, assumeRoleCreds *credentials.Credentials) (*session.Session, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/Sts/STS/
cmd/infra/aws/util/sts.go
Outdated
Credentials Credentials `json:"Credentials"` | ||
} | ||
|
||
rawStsCreds, err := os.ReadFile(credentialsFile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/Sts/STS/
cmd/infra/aws/util/util.go
Outdated
AWSCredentialsFile string | ||
|
||
RoleArn string | ||
StsCredentialsFile string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/Sts/STS/
/label tide/merge-method-squash |
cmd/cluster/aws/destroy.go
Outdated
return nil | ||
} | ||
|
||
if opts.AWSPlatform.AWSCredentialsOpts.AWSCredentialsFile == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we're doing this check again? Wouldn't Validate above catch it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate above is executed when the CredentialsSecret is not set.
If CredentialsSecret is set we want to only check that role-arn
is required, but only if AWSCredentialsFile is not set. i.e. AWSCredentialsFile has priority over credentialSecret (this is the current behavior, I can change it if it doesn't make sense)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In some follow-up, might be good to check with whoever is using this secret flag thing and see if they can stop, it's a huge hassle to support it and asking folks to pass in the options they need verbatim would be a lot easier to reason about.
/approve |
@@ -167,7 +168,7 @@ type KubevirtPlatformCreateOptions struct { | |||
} | |||
|
|||
type AWSPlatformOptions struct { | |||
AWSCredentialsFile string | |||
AWSCredentialsOpts awsutil.AWSCredentialsOptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You do not need to change this now, but FWIW if you had embedded the awsutil.AWSCredentialsOptions
it would have required a much smaller diff (and a lot less typing!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Couple small comments
@@ -48,11 +46,13 @@ func NewCreateCommand(opts *core.CreateOptions) *cobra.Command { | |||
cmd.Flags().StringVar(&opts.AWSPlatform.EndpointAccess, "endpoint-access", opts.AWSPlatform.EndpointAccess, "Access for control plane endpoints (Public, PublicAndPrivate, Private)") | |||
cmd.Flags().StringVar(&opts.AWSPlatform.EtcdKMSKeyARN, "kms-key-arn", opts.AWSPlatform.EtcdKMSKeyARN, "The ARN of the KMS key to use for Etcd encryption. If not supplied, etcd encryption will default to using a generated AESCBC key.") | |||
cmd.Flags().BoolVar(&opts.AWSPlatform.EnableProxy, "enable-proxy", opts.AWSPlatform.EnableProxy, "If a proxy should be set up, rather than allowing direct internet access from the nodes") | |||
cmd.Flags().StringVar(&opts.CredentialSecretName, "secret-creds", opts.CredentialSecretName, "A Kubernetes secret with needed AWS platform credentials: aws-creds, pull-secret, and a base-domain value. The secret must exist in the supplied \"--namespace\". If a value is provided through the flag '--pull-secret', that value will override the pull-secret value in 'secret-creds'.") | |||
cmd.Flags().StringVar(&opts.CredentialSecretName, "secret-creds", opts.CredentialSecretName, "A Kubernetes secret with needed AWS platform credentials: sts-creds, pull-secret, and a base-domain value. The secret must exist in the supplied \"--namespace\". If a value is provided through the flag '--pull-secret', that value will override the pull-secret value in 'secret-creds'.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing what we expect in this secret is breaking for any existing users of the CLI that are using the flag and secret today - if we have such users, this is not safe to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is used by ACM, we already communicated the new changes with them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the path for this not to be breaking, then? They will have to update the secret to contain both values before this merges and is rolled out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need this to merge today on our side. I don't how/when they roll out new versions.
cmd/cluster/aws/destroy.go
Outdated
return nil | ||
} | ||
|
||
if opts.AWSPlatform.AWSCredentialsOpts.AWSCredentialsFile == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In some follow-up, might be good to check with whoever is using this secret flag thing and see if they can stop, it's a huge hassle to support it and asking folks to pass in the options they need verbatim would be a lot easier to reason about.
cmd/cluster/aws/destroy.go
Outdated
@@ -138,20 +138,26 @@ func DestroyCluster(ctx context.Context, o *core.DestroyOptions) error { | |||
return core.DestroyCluster(ctx, hostedCluster, o, destroyPlatformSpecifics) | |||
} | |||
|
|||
// ValidateCredentialInfo validates if the credentials secret name is empty, the aws-creds is not empty; validates if | |||
// ValidateCredentialInfo validates if the credentials secret name is empty, the aws-creds or sts-creds mutually exclusive and are not empty; validates if | |||
// the credentials secret is not empty, that it can be retrieved. | |||
func ValidateCredentialInfo(opts *core.DestroyOptions) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this any different from the ValidateCreateCredentialInfo(opts *core.CreateOptions) error
? If not, can it be written as ValidateAWSCredentialInfo(opts *core.AWSCredentialsOpts, secret string) error
and shared?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or, share using a larger struct that has one more field for the secret and closes over binding the flag, validating, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ValidateCreateCredentialInfo
also validates the pull-secret while this one doesn't, so I don't see how we can share the func easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about
func ValidateCreateCredentialInfo(opts *core.CreateOptions) error {
if err := ValidateAWSCredentialInfo(opts.AWSPlatform.AWSCredentialsOpts, opts.CredentialSecretName); err != nil {
return err
}
if len(opts.CredentialSecretName) == 0 {
if err := util.ValidateRequiredOption("pull-secret", opts.PullSecretFile); err != nil {
return err
}
}
return nil
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed
cmd/infra/aws/util/util.go
Outdated
|
||
func (opts *AWSCredentialsOptions) BindFlags(flags *pflag.FlagSet) { | ||
flags.StringVar(&opts.AWSCredentialsFile, "aws-creds", opts.AWSCredentialsFile, "Path to an AWS credentials file") | ||
flags.StringVar(&opts.RoleArn, "role-arn", opts.RoleArn, "The ARN of the role to assume.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you factor one of Bind*
to call the other? We do not want the flag names etc to be different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how would you do that? one marks the flags as required, the other one doesn't
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would personally not bother with the cobra.MarkFlagRequired
business - you need to have the correct logic in Validate()
anyway and with the programmatic re-use of the Options
struct in e2e, so it's not really buying us anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cobra.MarkFlagRequired
also helps prioritize those fields with auto completion. But not very important.
Addressed.
cmd/infra/aws/util/util.go
Outdated
return NewSTSSession(agent, opts.RoleArn, region, creds) | ||
} | ||
|
||
return nil, fmt.Errorf("either --aws-creds or --sts-creds or --secret-creds flag must be set") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: keep the flag-related comments in the Validate()
. This kind of function (GetSession()
, etc) is most useful when being re-used in code, for instance how we have the e2e today creating Options
structs and using them as-is. In that kind of context, there are no flags and error messages about --aws-creds
from the internals of the e2e framework (or whatever other programmatic consumer there is for this) are harder to follow. This error might read something like
return nil, errors.New("could not create AWS session, no credentials were given")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: csrwng, Patryk-Stefanski, stevekuznetsov The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/hold Revision d8dd04e was retested 3 times: holding |
/unhold |
/override ci/prow/e2e-kubevirt-aws-ovn |
@muraee: Overrode contexts on behalf of muraee: ci/prow/e2e-kubevirt-aws-ovn In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
@Patryk-Stefanski: The following test failed, say
Full PR test history. Your PR dashboard. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
936f82b
into
openshift:main
/cherry-pick release-4.16 |
@celebdor: new pull request created: #4078 In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
* HOSTEDCP-1561: Move HCP CLI to STS mode * HOSTEDCP-1561: Addressing comments * HOSTEDCP-1561: enable --secret-creds flag with sts * HOSTEDCP-1561 extract sts cred specifics from sts-creds file * refactor * addressed review comments * more refactor --------- Co-authored-by: Mulham Raee <mraee@redhat.com>
What this PR does / why we need it:
Which issue(s) this PR fixes (optional, use
fixes #<issue_number>(, fixes #<issue_number>, ...)
format, where issue_number might be a GitHub issue, or a Jira story:Fixes #
Checklist