From 202bb34cfe0eac68ce0f3b5d4d12a26dcaad8e1a Mon Sep 17 00:00:00 2001 From: Christopher Fry Date: Tue, 20 Dec 2022 01:04:15 +0000 Subject: [PATCH 1/3] rollouts: add package discovery --- rollouts/api/v1alpha1/rollout_types.go | 35 +++++- .../api/v1alpha1/zz_generated.deepcopy.go | 64 +++++++++++ .../crd/bases/gitops.kpt.dev_rollouts.yaml | 52 +++++++-- .../samples/gitops_v1alpha1_rollout.yaml | 9 +- rollouts/controllers/rollout_controller.go | 20 ++++ rollouts/go.mod | 2 + rollouts/go.sum | 5 + .../pkg/packagediscovery/packagediscovery.go | 104 ++++++++++++++++++ .../packagediscovery/packagediscovery_test.go | 30 +++++ 9 files changed, 309 insertions(+), 12 deletions(-) create mode 100644 rollouts/pkg/packagediscovery/packagediscovery.go create mode 100644 rollouts/pkg/packagediscovery/packagediscovery_test.go diff --git a/rollouts/api/v1alpha1/rollout_types.go b/rollouts/api/v1alpha1/rollout_types.go index 29ffccc7e8..dfcbb7f010 100644 --- a/rollouts/api/v1alpha1/rollout_types.go +++ b/rollouts/api/v1alpha1/rollout_types.go @@ -30,20 +30,47 @@ type RolloutSpec struct { // Description is a user friendly description of this Rollout. Description string `json:"description,omitempty"` + // Packages source for this Rollout. + Packages PackagesConfig `json:"packages"` + // Targets specifies the clusters that will receive the KRM config packages. Targets ClusterTargetSelector `json:"targets,omitempty"` - - // PackageSourceType identifies how the KRM config unit will be sourced. - PackageSourceType PackageSourceType `json:"packageSourceType,omitempty"` } type ClusterTargetSelector struct { Selector *metav1.LabelSelector `json:"selector,omitempty"` } -// +kubebuilder:validation:Enum=gitRepo;gitDir +// +kubebuilder:validation:Enum=git type PackageSourceType string +// PackagesConfig defines the packages the Rollout should deploy. +type PackagesConfig struct { + SourceType PackageSourceType `json:"sourceType"` + + Git GitSource `json:"git"` +} + +// GitSource defines the packages source in Git. +type GitSource struct { + GitRepoSelector GitSelector `json:"selector"` +} + +// GitSelector defines the selector to apply to Git. +type GitSelector struct { + Org string `json:"org"` + Name string `json:"name"` + PackagesPath string `json:"packagesPath"` + Revision string `json:"revision"` + SecretRef SecretReference `json:"secretRef,omitempty"` +} + +// SecretReference contains the reference to the secret +type SecretReference struct { + // Name represents the secret name + Name string `json:"name,omitempty"` +} + // RolloutStatus defines the observed state of Rollout type RolloutStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster diff --git a/rollouts/api/v1alpha1/zz_generated.deepcopy.go b/rollouts/api/v1alpha1/zz_generated.deepcopy.go index a5a6ef7bc2..0cfee70ff8 100644 --- a/rollouts/api/v1alpha1/zz_generated.deepcopy.go +++ b/rollouts/api/v1alpha1/zz_generated.deepcopy.go @@ -46,6 +46,54 @@ func (in *ClusterTargetSelector) DeepCopy() *ClusterTargetSelector { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitSelector) DeepCopyInto(out *GitSelector) { + *out = *in + out.SecretRef = in.SecretRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitSelector. +func (in *GitSelector) DeepCopy() *GitSelector { + if in == nil { + return nil + } + out := new(GitSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitSource) DeepCopyInto(out *GitSource) { + *out = *in + out.GitRepoSelector = in.GitRepoSelector +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitSource. +func (in *GitSource) DeepCopy() *GitSource { + if in == nil { + return nil + } + out := new(GitSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackagesConfig) DeepCopyInto(out *PackagesConfig) { + *out = *in + out.Git = in.Git +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackagesConfig. +func (in *PackagesConfig) DeepCopy() *PackagesConfig { + if in == nil { + return nil + } + out := new(PackagesConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Rollout) DeepCopyInto(out *Rollout) { *out = *in @@ -108,6 +156,7 @@ func (in *RolloutList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RolloutSpec) DeepCopyInto(out *RolloutSpec) { *out = *in + out.Packages = in.Packages in.Targets.DeepCopyInto(&out.Targets) } @@ -135,3 +184,18 @@ func (in *RolloutStatus) DeepCopy() *RolloutStatus { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretReference) DeepCopyInto(out *SecretReference) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretReference. +func (in *SecretReference) DeepCopy() *SecretReference { + if in == nil { + return nil + } + out := new(SecretReference) + in.DeepCopyInto(out) + return out +} diff --git a/rollouts/config/crd/bases/gitops.kpt.dev_rollouts.yaml b/rollouts/config/crd/bases/gitops.kpt.dev_rollouts.yaml index 22cad1f72d..fa6a3dea68 100644 --- a/rollouts/config/crd/bases/gitops.kpt.dev_rollouts.yaml +++ b/rollouts/config/crd/bases/gitops.kpt.dev_rollouts.yaml @@ -38,13 +38,49 @@ spec: description: description: Description is a user friendly description of this Rollout. type: string - packageSourceType: - description: PackageSourceType identifies how the KRM config unit - will be sourced. - enum: - - gitRepo - - gitDir - type: string + packages: + description: Packages source for this Rollout. + properties: + git: + description: GitSource defines the packages source in Git. + properties: + selector: + description: GitSelector defines the selector to apply to + Git. + properties: + name: + type: string + org: + type: string + packagesPath: + type: string + revision: + type: string + secretRef: + description: SecretReference contains the reference to + the secret + properties: + name: + description: Name represents the secret name + type: string + type: object + required: + - name + - org + - packagesPath + - revision + type: object + required: + - selector + type: object + sourceType: + enum: + - git + type: string + required: + - git + - sourceType + type: object targets: description: Targets specifies the clusters that will receive the KRM config packages. @@ -98,6 +134,8 @@ spec: type: object x-kubernetes-map-type: atomic type: object + required: + - packages type: object status: description: RolloutStatus defines the observed state of Rollout diff --git a/rollouts/config/samples/gitops_v1alpha1_rollout.yaml b/rollouts/config/samples/gitops_v1alpha1_rollout.yaml index 9363d09268..ddad950746 100644 --- a/rollouts/config/samples/gitops_v1alpha1_rollout.yaml +++ b/rollouts/config/samples/gitops_v1alpha1_rollout.yaml @@ -23,8 +23,15 @@ metadata: app.kubernetes.io/created-by: rollouts name: rollout-sample spec: - packageSourceType: gitRepo description: "this is first rollout :)" + packages: + sourceType: git + git: + selector: + org: GoogleContainerTools + name: kpt-samples + packagesPath: "*" + revision: main targets: selector: matchExpressions: diff --git a/rollouts/controllers/rollout_controller.go b/rollouts/controllers/rollout_controller.go index a8a150bdfc..9f4c7471b4 100644 --- a/rollouts/controllers/rollout_controller.go +++ b/rollouts/controllers/rollout_controller.go @@ -30,6 +30,7 @@ import ( gkeclusterapis "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/container/v1beta1" gitopsv1alpha1 "github.com/GoogleContainerTools/kpt/rollouts/api/v1alpha1" "github.com/GoogleContainerTools/kpt/rollouts/pkg/clusterstore" + "github.com/GoogleContainerTools/kpt/rollouts/pkg/packagediscovery" ) var ( @@ -111,6 +112,25 @@ func (r *RolloutReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct } r.testClusterClient(ctx, cl) } + + if err := r.Get(ctx, req.NamespacedName, &rollout); err != nil { + logger.Error(err, "unable to fetch Rollout") + // we'll ignore not-found errors, since they can't be fixed by an immediate + // requeue (we'll need to wait for a new notification), and we can get them + // on deleted requests. + return ctrl.Result{}, client.IgnoreNotFound(err) + } + + packageDiscoveryClient := packagediscovery.NewPackageDiscovery(rollout.Spec.Packages, r.Client, req.Namespace) + + discoveredPackages, err := packageDiscoveryClient.GetPackages(ctx) + if err != nil { + logger.Error(err, "package discovery failed") + return ctrl.Result{}, client.IgnoreNotFound(err) + } + + logger.Info("discovered packages", "count", len(discoveredPackages), "packages", discoveredPackages) + return ctrl.Result{}, err } diff --git a/rollouts/go.mod b/rollouts/go.mod index fb3910db01..a66e878146 100644 --- a/rollouts/go.mod +++ b/rollouts/go.mod @@ -6,6 +6,7 @@ require ( cloud.google.com/go/iam v0.7.0 github.com/GoogleCloudPlatform/k8s-config-connector v1.98.0 github.com/golang/protobuf v1.5.2 + github.com/google/go-github/v48 v48.2.0 github.com/onsi/ginkgo/v2 v2.1.6 github.com/onsi/gomega v1.20.1 golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 @@ -43,6 +44,7 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/gnostic v0.6.9 // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect diff --git a/rollouts/go.sum b/rollouts/go.sum index b39e69ffe5..713d2ff8df 100644 --- a/rollouts/go.sum +++ b/rollouts/go.sum @@ -177,11 +177,16 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v48 v48.2.0 h1:68puzySE6WqUY9KWmpOsDEQfDZsso98rT6pZcz9HqcE= +github.com/google/go-github/v48 v48.2.0/go.mod h1:dDlehKBDo850ZPvCTK0sEqTCVWcrGl2LcDiajkYi89Y= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/rollouts/pkg/packagediscovery/packagediscovery.go b/rollouts/pkg/packagediscovery/packagediscovery.go new file mode 100644 index 0000000000..423b7a5449 --- /dev/null +++ b/rollouts/pkg/packagediscovery/packagediscovery.go @@ -0,0 +1,104 @@ +package packagediscovery + +import ( + "context" + "fmt" + "net/http" + "path/filepath" + + gitopsv1alpha1 "github.com/GoogleContainerTools/kpt/rollouts/api/v1alpha1" + "github.com/google/go-github/v48/github" + "golang.org/x/oauth2" + coreapi "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type PackageDiscovery struct { + config gitopsv1alpha1.PackagesConfig + client client.Client + namespace string +} + +type DiscoveredPackage struct { + Org string + Name string + Directory string + Revision string +} + +func NewPackageDiscovery(config gitopsv1alpha1.PackagesConfig, client client.Client, namespace string) *PackageDiscovery { + return &PackageDiscovery{ + config: config, + client: client, + namespace: namespace, + } +} + +func (d *PackageDiscovery) GetPackages(ctx context.Context) ([]DiscoveredPackage, error) { + gitRepoSelector := d.config.Git.GitRepoSelector + gitClient, err := d.getGitHubClient(ctx) + if err != nil { + return nil, fmt.Errorf("unable to create git client: %w", err) + } + + tree, _, err := gitClient.Git.GetTree(ctx, gitRepoSelector.Org, gitRepoSelector.Name, gitRepoSelector.Revision, true) + if err != nil { + return nil, fmt.Errorf("unable to fetch tree from git: %w", err) + } + + allPaths := []string{} + for _, entry := range tree.Entries { + if *entry.Type == "tree" { + allPaths = append(allPaths, *entry.Path) + } + } + + packagesPaths := discoverPackagePaths(gitRepoSelector.PackagesPath, allPaths) + + discoveredPackages := []DiscoveredPackage{} + + for _, path := range packagesPaths { + thisDiscoveredPackage := DiscoveredPackage{Org: gitRepoSelector.Org, Name: gitRepoSelector.Name, Revision: gitRepoSelector.Revision, Directory: path} + discoveredPackages = append(discoveredPackages, thisDiscoveredPackage) + } + + return discoveredPackages, nil +} + +func (d *PackageDiscovery) getGitHubClient(ctx context.Context) (*github.Client, error) { + gitRepoSelector := d.config.Git.GitRepoSelector + + httpClient := &http.Client{} + + if secretName := gitRepoSelector.SecretRef.Name; secretName != "" { + var repositorySecret coreapi.Secret + key := client.ObjectKey{Namespace: d.namespace, Name: secretName} + if err := d.client.Get(ctx, key, &repositorySecret); err != nil { + return nil, fmt.Errorf("cannot retrieve git credentials %s: %v", key, err) + } + + accessToken := string(repositorySecret.Data["password"]) + + ts := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: accessToken}, + ) + + httpClient = oauth2.NewClient(ctx, ts) + } + + gitClient := github.NewClient(httpClient) + + return gitClient, nil +} + +func discoverPackagePaths(pattern string, paths []string) []string { + packagePaths := []string{} + + for _, path := range paths { + if isMatch, _ := filepath.Match(pattern, path); isMatch { + packagePaths = append(packagePaths, path) + } + } + + return packagePaths +} diff --git a/rollouts/pkg/packagediscovery/packagediscovery_test.go b/rollouts/pkg/packagediscovery/packagediscovery_test.go new file mode 100644 index 0000000000..aa61ae2664 --- /dev/null +++ b/rollouts/pkg/packagediscovery/packagediscovery_test.go @@ -0,0 +1,30 @@ +package packagediscovery + +import ( + "reflect" + "testing" +) + +var DiscoverPackagePaths = discoverPackagePaths + +func TestDiscoverPackagePaths(t *testing.T) { + tests := []struct { + paths []string + pattern string + want []string + }{ + {paths: []string{"dev", "prod", "dev/package-a", "dev/paackage-b", "prod/package-c"}, pattern: "dev/*", want: []string{"dev/package-a", "dev/package-b"}}, + {paths: []string{"package-a", "package-b", "package-a/dev", "package-a/prod", "package-b/dev"}, pattern: "*/dev", want: []string{"package-a/dev", "package-b/dev"}}, + {paths: []string{"package-a", "package-b", "package-a/dev", "package-a/prod", "package-b/dev"}, pattern: "package-*/prod", want: []string{"package-a/prod"}}, + {paths: []string{"package-a", "package-b", "package-a/dev", "package-a/prod", "package-b/dev"}, pattern: "package-a/dev", want: []string{"package-a/dev"}}, + {paths: []string{"parent", "parent/package-a", "parent/package-b", "parent/package-a/dev", "parent/package-a/prod", "parent/package-b/dev"}, pattern: "parent/*-a/dev", want: []string{"parent/package-a/dev"}}, + {paths: []string{"package-a", "package-b", "package-a/crds", "package-a/crs", "package-b/crds"}, pattern: "package-*", want: []string{"package-a", "package-b"}}, + } + + for _, tc := range tests { + got := DiscoverPackagePaths(tc.pattern, tc.paths) + if !reflect.DeepEqual(tc.want, got) { + t.Fatalf("expected: %v, got: %v", tc.want, got) + } + } +} From 637f98daa4d3bc92a493d94220dc7227ccbdafb5 Mon Sep 17 00:00:00 2001 From: Christopher Fry Date: Wed, 21 Dec 2022 18:17:38 +0000 Subject: [PATCH 2/3] add license headers --- rollouts/pkg/packagediscovery/packagediscovery.go | 14 ++++++++++++++ .../pkg/packagediscovery/packagediscovery_test.go | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/rollouts/pkg/packagediscovery/packagediscovery.go b/rollouts/pkg/packagediscovery/packagediscovery.go index 423b7a5449..603e861c2e 100644 --- a/rollouts/pkg/packagediscovery/packagediscovery.go +++ b/rollouts/pkg/packagediscovery/packagediscovery.go @@ -1,3 +1,17 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package packagediscovery import ( diff --git a/rollouts/pkg/packagediscovery/packagediscovery_test.go b/rollouts/pkg/packagediscovery/packagediscovery_test.go index aa61ae2664..145add4367 100644 --- a/rollouts/pkg/packagediscovery/packagediscovery_test.go +++ b/rollouts/pkg/packagediscovery/packagediscovery_test.go @@ -1,3 +1,17 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package packagediscovery import ( From b96d0ff19d307cff3aef16e07df3cfb6072dae78 Mon Sep 17 00:00:00 2001 From: Christopher Fry Date: Wed, 21 Dec 2022 19:08:31 +0000 Subject: [PATCH 3/3] rename path to directory --- rollouts/api/v1alpha1/rollout_types.go | 10 ++++---- .../crd/bases/gitops.kpt.dev_rollouts.yaml | 6 ++--- .../samples/gitops_v1alpha1_rollout.yaml | 2 +- .../pkg/packagediscovery/packagediscovery.go | 14 +++++------ .../packagediscovery/packagediscovery_test.go | 24 +++++++++---------- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/rollouts/api/v1alpha1/rollout_types.go b/rollouts/api/v1alpha1/rollout_types.go index dfcbb7f010..9cf9992e74 100644 --- a/rollouts/api/v1alpha1/rollout_types.go +++ b/rollouts/api/v1alpha1/rollout_types.go @@ -58,11 +58,11 @@ type GitSource struct { // GitSelector defines the selector to apply to Git. type GitSelector struct { - Org string `json:"org"` - Name string `json:"name"` - PackagesPath string `json:"packagesPath"` - Revision string `json:"revision"` - SecretRef SecretReference `json:"secretRef,omitempty"` + Org string `json:"org"` + Name string `json:"name"` + Directory string `json:"directory"` + Revision string `json:"revision"` + SecretRef SecretReference `json:"secretRef,omitempty"` } // SecretReference contains the reference to the secret diff --git a/rollouts/config/crd/bases/gitops.kpt.dev_rollouts.yaml b/rollouts/config/crd/bases/gitops.kpt.dev_rollouts.yaml index fa6a3dea68..adc71dba3f 100644 --- a/rollouts/config/crd/bases/gitops.kpt.dev_rollouts.yaml +++ b/rollouts/config/crd/bases/gitops.kpt.dev_rollouts.yaml @@ -48,12 +48,12 @@ spec: description: GitSelector defines the selector to apply to Git. properties: + directory: + type: string name: type: string org: type: string - packagesPath: - type: string revision: type: string secretRef: @@ -65,9 +65,9 @@ spec: type: string type: object required: + - directory - name - org - - packagesPath - revision type: object required: diff --git a/rollouts/config/samples/gitops_v1alpha1_rollout.yaml b/rollouts/config/samples/gitops_v1alpha1_rollout.yaml index ddad950746..80c7e68026 100644 --- a/rollouts/config/samples/gitops_v1alpha1_rollout.yaml +++ b/rollouts/config/samples/gitops_v1alpha1_rollout.yaml @@ -30,7 +30,7 @@ spec: selector: org: GoogleContainerTools name: kpt-samples - packagesPath: "*" + directory: "*" revision: main targets: selector: diff --git a/rollouts/pkg/packagediscovery/packagediscovery.go b/rollouts/pkg/packagediscovery/packagediscovery.go index 603e861c2e..f8ccfaccb8 100644 --- a/rollouts/pkg/packagediscovery/packagediscovery.go +++ b/rollouts/pkg/packagediscovery/packagediscovery.go @@ -67,7 +67,7 @@ func (d *PackageDiscovery) GetPackages(ctx context.Context) ([]DiscoveredPackage } } - packagesPaths := discoverPackagePaths(gitRepoSelector.PackagesPath, allPaths) + packagesPaths := filterDirectories(gitRepoSelector.Directory, allPaths) discoveredPackages := []DiscoveredPackage{} @@ -105,14 +105,14 @@ func (d *PackageDiscovery) getGitHubClient(ctx context.Context) (*github.Client, return gitClient, nil } -func discoverPackagePaths(pattern string, paths []string) []string { - packagePaths := []string{} +func filterDirectories(pattern string, directories []string) []string { + filteredDirectories := []string{} - for _, path := range paths { - if isMatch, _ := filepath.Match(pattern, path); isMatch { - packagePaths = append(packagePaths, path) + for _, directory := range directories { + if isMatch, _ := filepath.Match(pattern, directory); isMatch { + filteredDirectories = append(filteredDirectories, directory) } } - return packagePaths + return filteredDirectories } diff --git a/rollouts/pkg/packagediscovery/packagediscovery_test.go b/rollouts/pkg/packagediscovery/packagediscovery_test.go index 145add4367..9adae5281a 100644 --- a/rollouts/pkg/packagediscovery/packagediscovery_test.go +++ b/rollouts/pkg/packagediscovery/packagediscovery_test.go @@ -19,24 +19,24 @@ import ( "testing" ) -var DiscoverPackagePaths = discoverPackagePaths +var FilterDirectories = filterDirectories -func TestDiscoverPackagePaths(t *testing.T) { +func TestFilterDirectories(t *testing.T) { tests := []struct { - paths []string - pattern string - want []string + directories []string + pattern string + want []string }{ - {paths: []string{"dev", "prod", "dev/package-a", "dev/paackage-b", "prod/package-c"}, pattern: "dev/*", want: []string{"dev/package-a", "dev/package-b"}}, - {paths: []string{"package-a", "package-b", "package-a/dev", "package-a/prod", "package-b/dev"}, pattern: "*/dev", want: []string{"package-a/dev", "package-b/dev"}}, - {paths: []string{"package-a", "package-b", "package-a/dev", "package-a/prod", "package-b/dev"}, pattern: "package-*/prod", want: []string{"package-a/prod"}}, - {paths: []string{"package-a", "package-b", "package-a/dev", "package-a/prod", "package-b/dev"}, pattern: "package-a/dev", want: []string{"package-a/dev"}}, - {paths: []string{"parent", "parent/package-a", "parent/package-b", "parent/package-a/dev", "parent/package-a/prod", "parent/package-b/dev"}, pattern: "parent/*-a/dev", want: []string{"parent/package-a/dev"}}, - {paths: []string{"package-a", "package-b", "package-a/crds", "package-a/crs", "package-b/crds"}, pattern: "package-*", want: []string{"package-a", "package-b"}}, + {directories: []string{"dev", "prod", "dev/package-a", "dev/paackage-b", "prod/package-c"}, pattern: "dev/*", want: []string{"dev/package-a", "dev/package-b"}}, + {directories: []string{"package-a", "package-b", "package-a/dev", "package-a/prod", "package-b/dev"}, pattern: "*/dev", want: []string{"package-a/dev", "package-b/dev"}}, + {directories: []string{"package-a", "package-b", "package-a/dev", "package-a/prod", "package-b/dev"}, pattern: "package-*/prod", want: []string{"package-a/prod"}}, + {directories: []string{"package-a", "package-b", "package-a/dev", "package-a/prod", "package-b/dev"}, pattern: "package-a/dev", want: []string{"package-a/dev"}}, + {directories: []string{"parent", "parent/package-a", "parent/package-b", "parent/package-a/dev", "parent/package-a/prod", "parent/package-b/dev"}, pattern: "parent/*-a/dev", want: []string{"parent/package-a/dev"}}, + {directories: []string{"package-a", "package-b", "package-a/crds", "package-a/crs", "package-b/crds"}, pattern: "package-*", want: []string{"package-a", "package-b"}}, } for _, tc := range tests { - got := DiscoverPackagePaths(tc.pattern, tc.paths) + got := FilterDirectories(tc.pattern, tc.directories) if !reflect.DeepEqual(tc.want, got) { t.Fatalf("expected: %v, got: %v", tc.want, got) }