diff --git a/pkg/registry/porch/fieldselector.go b/pkg/registry/porch/fieldselector.go index d2b293d3..1c83b4a9 100644 --- a/pkg/registry/porch/fieldselector.go +++ b/pkg/registry/porch/fieldselector.go @@ -17,6 +17,7 @@ package porch import ( "fmt" + "github.com/nephio-project/porch/api/porch/v1alpha1" "github.com/nephio-project/porch/pkg/repository" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/fields" @@ -46,6 +47,8 @@ func convertPackageRevisionFieldSelector(label, value string) (internalLabel, in return label, value, nil case "spec.revision", "spec.packageName", "spec.repository": return label, value, nil + case "spec.workspaceName", "spec.lifecycle": + return label, value, nil default: return "", "", fmt.Errorf("%q is not a known field selector", label) } @@ -151,6 +154,19 @@ func parsePackageRevisionFieldSelector(fieldSelector fields.Selector) (packageRe filter.Package = requirement.Value case "spec.repository": filter.Repository = requirement.Value + case "spec.workspaceName": + filter.WorkspaceName = v1alpha1.WorkspaceName(requirement.Value) + case "spec.lifecycle": + v := v1alpha1.PackageRevisionLifecycle(requirement.Value) + switch v { + case v1alpha1.PackageRevisionLifecycleDraft, + v1alpha1.PackageRevisionLifecycleProposed, + v1alpha1.PackageRevisionLifecyclePublished, + v1alpha1.PackageRevisionLifecycleDeletionProposed: + filter.Lifecycle = v + default: + return filter, apierrors.NewBadRequest(fmt.Sprintf("unsupported fieldSelector value %q for field %q", requirement.Value, requirement.Field)) + } default: return filter, apierrors.NewBadRequest(fmt.Sprintf("unknown fieldSelector field %q", requirement.Field)) diff --git a/pkg/repository/repository.go b/pkg/repository/repository.go index f6a7076b..2bd0b041 100644 --- a/pkg/repository/repository.go +++ b/pkg/repository/repository.go @@ -142,6 +142,9 @@ type ListPackageRevisionFilter struct { // Revision matches the revision of the package (spec.revision) Revision string + + // Lifecycle matches the spec.lifecycle of the package + Lifecycle v1alpha1.PackageRevisionLifecycle } // Matches returns true if the provided PackageRevision satisfies the conditions in the filter. @@ -158,6 +161,9 @@ func (f *ListPackageRevisionFilter) Matches(p PackageRevision) bool { if f.KubeObjectName != "" && f.KubeObjectName != p.KubeObjectName() { return false } + if f.Lifecycle != "" && f.Lifecycle != p.Lifecycle() { + return false + } return true } diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index fc8e25f2..e1621045 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -33,6 +33,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/types" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" "sigs.k8s.io/controller-runtime/pkg/client" @@ -2371,5 +2372,45 @@ func (t *PorchSuite) TestUniquenessOfUIDs(ctx context.Context) { } uids[pr.UID] = &pr } +} + +func (t *PorchSuite) TestPackageRevisionFieldselectors(ctx context.Context) { + t.registerGitRepositoryF(ctx, testBlueprintsRepo, "test-blueprints", "") + + prList := porchapi.PackageRevisionList{} + + wsName := "v1" + wsSelector := client.MatchingFields(fields.Set{"spec.workspaceName": wsName}) + t.ListE(ctx, &prList, client.InNamespace(t.namespace), wsSelector) + if len(prList.Items) == 0 { + t.Errorf("Expected at least one PackageRevision with workspaceName=%q, but got none", wsName) + } + for _, pr := range prList.Items { + if pr.Spec.WorkspaceName != porchapi.WorkspaceName(wsName) { + t.Errorf("PackageRevision %s workspaceName: want %q, but got %q", pr.Name, wsName, pr.Spec.WorkspaceName) + } + } + publishedSelector := client.MatchingFields(fields.Set{"spec.lifecycle": string(porchapi.PackageRevisionLifecyclePublished)}) + t.ListE(ctx, &prList, client.InNamespace(t.namespace), publishedSelector) + if len(prList.Items) == 0 { + t.Errorf("Expected at least one PackageRevision with lifecycle=%q, but got none", porchapi.PackageRevisionLifecyclePublished) + } + for _, pr := range prList.Items { + if pr.Spec.Lifecycle != porchapi.PackageRevisionLifecyclePublished { + t.Errorf("PackageRevision %s lifecycle: want %q, but got %q", pr.Name, porchapi.PackageRevisionLifecyclePublished, pr.Spec.Lifecycle) + } + } + + draftSelector := client.MatchingFields(fields.Set{"spec.lifecycle": string(porchapi.PackageRevisionLifecycleDraft)}) + t.ListE(ctx, &prList, client.InNamespace(t.namespace), draftSelector) + // TODO: add draft packages to the test repo + // if len(prList.Items) == 0 { + // t.Errorf("Expected at least one PackageRevision with lifecycle=%q, but got none", porchapi.PackageRevisionLifecycleDraft) + // } + for _, pr := range prList.Items { + if pr.Spec.Lifecycle != porchapi.PackageRevisionLifecycleDraft { + t.Errorf("PackageRevision %s lifecycle: want %q, but got %q", pr.Name, porchapi.PackageRevisionLifecycleDraft, pr.Spec.Lifecycle) + } + } }