diff --git a/pkg/validation/external/removed_apis.go b/pkg/validation/external/removed_apis.go new file mode 100644 index 000000000..b93c9b311 --- /dev/null +++ b/pkg/validation/external/removed_apis.go @@ -0,0 +1,43 @@ +package external + +import ( + "github.com/operator-framework/api/pkg/manifests" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func GetRemovedAPIsOn1_25From(bundle *manifests.Bundle) map[string][]string { + deprecatedAPIs := make(map[string][]string) + for _, obj := range bundle.Objects { + switch usage := obj.GetObjectKind().(type) { + case *unstructured.Unstructured: + switch usage.GetAPIVersion() { + case "batch/v1beta1": + if usage.GetKind() == "CronJob" { + addDepUsage(deprecatedAPIs, usage) + } + case "discovery.k8s.io/v1beta1": + if usage.GetKind() == "EndpointSlice" { + addDepUsage(deprecatedAPIs, usage) + } + case "events.k8s.io/v1beta1": + if usage.GetKind() == "Event" { + addDepUsage(deprecatedAPIs, usage) + } + case "policy/v1beta1": + if usage.GetKind() == "PodDisruptionBudget" || usage.GetKind() == "PodSecurityPolicy" { + addDepUsage(deprecatedAPIs, usage) + } + case "node.k8s.io/v1beta1": + if usage.GetKind() == "RuntimeClass" { + addDepUsage(deprecatedAPIs, usage) + } + } + } + } + return deprecatedAPIs +} + +func addDepUsage(deprecatedAPIs map[string][]string, u *unstructured.Unstructured) map[string][]string { + deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], u.GetName()) + return deprecatedAPIs +} diff --git a/pkg/validation/external/removed_apis_test.go b/pkg/validation/external/removed_apis_test.go new file mode 100644 index 000000000..139cdef1e --- /dev/null +++ b/pkg/validation/external/removed_apis_test.go @@ -0,0 +1,57 @@ +package external + +import ( + "github.com/operator-framework/api/pkg/manifests" + "github.com/stretchr/testify/require" + "reflect" + "testing" +) + +func Test_getDeprecated1_25APIs(t *testing.T) { + + // Mock the expected result for ../internal/testdata/valid_bundle_v1beta1 + crdMock := make(map[string][]string) + crdMock["CRD"] = []string{"etcdbackups.etcd.database.coreos.com", "etcdclusters.etcd.database.coreos.com", "etcdrestores.etcd.database.coreos.com"} + + // Mock the expected result + otherKindsMock := make(map[string][]string) + otherKindsMock["PodDisruptionBudget"] = []string{"busybox-pdb"} + + bundleDirPrefix := "../internal/testdata/" // let's reuse the testdata, so we can avoid creating more + + type args struct { + bundleDir string + } + tests := []struct { + name string + args args + want map[string][]string + }{ + { + name: "should return an empty map when no deprecated apis are found", + args: args{ + bundleDir: bundleDirPrefix + "valid_bundle_v1", + }, + want: map[string][]string{}, + }, + { + name: "should return map with others kinds which are deprecated", + args: args{ + bundleDir: bundleDirPrefix + "bundle_with_deprecated_resources", + }, + want: otherKindsMock, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + // Validate the bundle object + bundle, err := manifests.GetBundleFromDir(tt.args.bundleDir) + require.NoError(t, err) + + if got := GetRemovedAPIsOn1_25From(bundle); !reflect.DeepEqual(got, tt.want) { + t.Errorf("getRemovedAPIsOn1_25From() = %v, want %v", got, tt.want) + } + }) + } +}