in ecr/ref.go [70:135]
func ParseImageURI(input string) (ECRSpec, error) {
input = strings.TrimPrefix(input, "https://")
// Matching on account, region
matches := ecrRegex.FindStringSubmatch(input)
if len(matches) < 3 {
return ECRSpec{}, errInvalidImageURI
}
account := matches[1]
region := matches[2]
// Get the correct partition given its region
partition, found := endpoints.PartitionForRegion(endpoints.DefaultPartitions(), region)
if !found {
return ECRSpec{}, errInvalidImageURI
}
// Need to include the full repository path and the imageID (e.g. /eks/image-name:tag)
tokens := strings.SplitN(input, "/", 2)
if len(tokens) != 2 {
return ECRSpec{}, errInvalidImageURI
}
fullRepoPath := tokens[len(tokens)-1]
// Run simple checks on the provided repository.
switch {
case
// Must not be empty
fullRepoPath == "",
// Must not have a partial/unsupplied label
strings.HasSuffix(fullRepoPath, ":"),
// Must not have a partial/unsupplied digest specifier
strings.HasSuffix(fullRepoPath, "@"):
return ECRSpec{}, errors.New("incomplete reference provided")
}
// Parse out image reference's to validate.
ref, err := reference.Parse(repositoryPrefix + fullRepoPath)
if err != nil {
return ECRSpec{}, err
}
// If the digest is provided, check that it is valid.
if ref.Digest() != "" {
err := ref.Digest().Validate()
// Digest may not be supported by the client despite it passing against
// a rudimentary check. The error is different in the passing case, so
// that's considered a passing check for unavailable digesters.
//
// https://github.com/opencontainers/go-digest/blob/ea51bea511f75cfa3ef6098cc253c5c3609b037a/digest.go#L110-L115
if err != nil && err != digest.ErrDigestUnsupported {
return ECRSpec{}, errors.Wrap(err, errInvalidImageURI.Error())
}
}
return ECRSpec{
Repository: strings.TrimPrefix(ref.Locator, repositoryPrefix),
Object: ref.Object,
arn: arn.ARN{
Partition: partition.ID(),
Service: arnServiceID,
Region: region,
AccountID: account,
Resource: ref.Locator,
},
}, nil
}