diff --git a/pkg/utils/url.go b/pkg/utils/url.go index d916d43..87ab23b 100644 --- a/pkg/utils/url.go +++ b/pkg/utils/url.go @@ -2,6 +2,7 @@ package utils import ( "fmt" + "regexp" "strings" "github.com/opencontainers/go-digest" @@ -28,7 +29,6 @@ type RepoURL struct { // and empty slice will be returned if no tags or digest is provided. func GenerateRepoURLs(url string, externalTagsOrDigest func(registry, repository string, ) (tagsOrDigest []string, err error)) ([]*RepoURL, error) { - var result []*RepoURL ref, err := reference.ParseNormalizedNamed(url) @@ -55,21 +55,47 @@ func GenerateRepoURLs(url string, externalTagsOrDigest func(registry, repository tagsOrDigest = append(tagsOrDigest, allTags...) } else { // url might have special tags - - // multiple tags exist - slice := strings.SplitN(url, ",", -1) - if len(slice) < 1 { - return nil, fmt.Errorf("invalid repository url: %v", url) - } - - ref, err = reference.ParseNormalizedNamed(slice[0]) - if err != nil { - return nil, fmt.Errorf("failed to parse first tag with url %v: %v", slice[0], err) + if strings.Contains(url, ":/") { + // regex exist, /*/, etc. + slice := strings.SplitN(url, ":/", 2) + if len(slice) != 2 || !strings.HasSuffix(slice[1], "/") { + return nil, fmt.Errorf("invalid tag regex url format %v, regex must start and end with \"/\"", url) + } + + urlWithoutTagOrDigest = slice[0] + regexStr := strings.TrimSuffix(slice[1], "/") + regex, err := regexp.Compile(regexStr) + if err != nil { + return nil, fmt.Errorf("invalid tag regex: \"%v\": %v", regexStr, err) + } + + registry, repo := getRegistryAndRepositoryFromURLWithoutTagOrDigest(urlWithoutTagOrDigest) + allTags, err := externalTagsOrDigest(registry, repo) + if err != nil { + return nil, fmt.Errorf("failed to get external tags: %v", err) + } + + for _, t := range allTags { + if regex.MatchString(t) { + tagsOrDigest = append(tagsOrDigest, t) + } + } + } else { + // multiple tags exist + slice := strings.SplitN(url, ",", -1) + if len(slice) < 1 { + return nil, fmt.Errorf("invalid repository url: %v", url) + } + + ref, err = reference.ParseNormalizedNamed(slice[0]) + if err != nil { + return nil, fmt.Errorf("failed to parse first tag with url %v: %v", slice[0], err) + } + + urlWithoutTagOrDigest = ref.(reference.NamedTagged).Name() + tagsOrDigest = append(tagsOrDigest, ref.(reference.NamedTagged).Tag()) + tagsOrDigest = append(tagsOrDigest, slice[1:]...) } - - urlWithoutTagOrDigest = ref.(reference.NamedTagged).Name() - tagsOrDigest = append(tagsOrDigest, ref.(reference.NamedTagged).Tag()) - tagsOrDigest = append(tagsOrDigest, slice[1:]...) } registry, repo := getRegistryAndRepositoryFromURLWithoutTagOrDigest(urlWithoutTagOrDigest) diff --git a/pkg/utils/url_test.go b/pkg/utils/url_test.go index 611656a..98a97cf 100644 --- a/pkg/utils/url_test.go +++ b/pkg/utils/url_test.go @@ -17,11 +17,15 @@ func TestURL(t *testing.T) { "127.0.0.1:300/library/nginx:v1,v2", "registry.cn-beijing.aliyuncs.com/hhyasdf/hybridnet@sha256:df2ef9e979fc063645dcbed51374233c6bcf4ab49308c0478702565e96b9bc9e", "nginx", + "test-regex/test:/b+/", } var repoURLs []*RepoURL for _, url := range urls { tmpUrls, err := GenerateRepoURLs(url, func(registry, repository string) (tags []string, err error) { + if registry == "test-regex" { + return []string{"aaa", "bbb"}, nil + } return []string{"latest"}, nil }) if err != nil { @@ -54,4 +58,5 @@ func TestURL(t *testing.T) { assert.Equal(t, "hhyasdf/hybridnet", repoURLs[7].GetRepo()) assert.Equal(t, DockerHubURL, repoURLs[8].GetRegistry()) + assert.Equal(t, "bbb", repoURLs[9].GetTagOrDigest()) }