-
Notifications
You must be signed in to change notification settings - Fork 27
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
Add suport for ECR repositorires #244
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
Signed-off-by: alexey.komyakov <[email protected]>
pkg/registry/checker.go
Outdated
keyChain, err := rc.providerRegistry.GetAuthKeychain(imageName) | ||
if err != nil { | ||
logrus.Warn("error while getting keychain for: ", err) | ||
return store.UnknownError |
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 suggest returning a more specific authentication error, similar to the implementation here:
availMode = store.AuthnFailure |
This would help clarify the nature of the failure, but I’m open to feedback if there’s a better approach.
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 suppose you're right.
Changed in last commit.
Signed-off-by: alexey.komyakov <[email protected]>
|
||
func (p ProviderRegistry) GetAuthKeychain(registryStr string) (authn.Keychain, error) { | ||
switch { | ||
case strings.Contains(registryStr, "amazonaws.com"): |
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.
lets user url.Parse
here and than check the URL with more accurate regex ^([0-9]{12})\.dkr\.ecr\.[a-z0-9-]+\.amazonaws\.com(\.cn)?$
} | ||
} | ||
|
||
func (p Provider) GetAuthKeychain(registryStr string) (authn.Keychain, 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.
func (p Provider) GetAuthKeychain(registryStr string) (authn.Keychain, error) { | |
func (p Provider) GetAuthKeychain(registry string) (authn.Keychain, error) { |
NIT: you do not need to add a variable type to a name
return nil, err | ||
} | ||
|
||
client := ecr.NewFromConfig(cfg) |
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 the client be cached in provider or do we need to reinitialize it on each execution?
} | ||
|
||
func awsRegionalClient(ctx context.Context, region string) (*ecr.Client, error) { | ||
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region)) |
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 assume config also cannot be changed and thus be cached.
return &customKeychain{authenticator: auth}, nil | ||
} | ||
|
||
func parseECRDetails(registryStr string) 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.
It is better to use regex with a capture group to highlight that we are extracting a region here.
Also please provide an example of an address of a ECR registry.
The name is also not good, lets use something like parseECRRegion
.
func NewProviderChain(pullSecretsGetter func(image string) []corev1.Secret) ProviderRegistry { | ||
return map[string]Provider{ | ||
"amazon": amazon.NewProvider(), | ||
"k8s": k8s.NewProvider(pullSecretsGetter), | ||
} | ||
} |
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 don't like that the generic chain accepts kubernetes specific options Can we avoid it by initializing each provider separately?
type customKeychain struct { | ||
authenticator authn.Authenticator | ||
} | ||
|
||
func (kc *customKeychain) Resolve(_ authn.Resource) (authn.Authenticator, error) { | ||
return kc.authenticator, 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.
What is this? The name is too broad. Is this an authn.Keychain
implementation?
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 an authn.Keychain implementation?
Yes it is
return nil, fmt.Errorf("error loading AWS config: %w", err) | ||
} | ||
|
||
authTokenOutput, err := ecrClient.GetAuthorizationToken(context.TODO(), &ecr.GetAuthorizationTokenInput{}) |
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 GetAuthorizationToken
called for each image request?
AuthorizationData
has the expiresAt
field, so I assume we can cache the token till this time and avoid flooding AWS with requests.
|
||
pullSecretsGetter := func(image string) []corev1.Secret { | ||
return rc.controllerIndexers.GetImagePullSecrets(image) | ||
} | ||
pc := providers.NewProviderChain(pullSecretsGetter) | ||
rc.providerRegistry = pc | ||
|
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.
pullSecretsGetter := func(image string) []corev1.Secret { | |
return rc.controllerIndexers.GetImagePullSecrets(image) | |
} | |
pc := providers.NewProviderChain(pullSecretsGetter) | |
rc.providerRegistry = pc | |
rc.providerRegistry = providers.NewProviderChain(rc.controllerIndexers.GetImagePullSecrets) |
Some users prefer to use in EKS clusters ECR without service accounts to authorize but with native support from ECR using IAM policies to provide credentials for their projects.
Exporter can't get any credentials from SA or from Secrets and falls with 401 Unauthorized exception.
This PR adds new libraries from AWS for work with their authorization methods.