diff --git a/openshift/tests-extension/.openshift-tests-extension/openshift_payload_olmv1.json b/openshift/tests-extension/.openshift-tests-extension/openshift_payload_olmv1.json index ad0f6e49f..ac181102a 100644 --- a/openshift/tests-extension/.openshift-tests-extension/openshift_payload_olmv1.json +++ b/openshift/tests-extension/.openshift-tests-extension/openshift_payload_olmv1.json @@ -476,7 +476,10 @@ }, { "name": "[sig-olmv1][OCPFeatureGate:NewOLM][Skipped:Disconnected] OLMv1 operator installation should install an openshift catalog cluster extension", - "labels": {}, + "originalName": "[sig-olmv1][OCPFeatureGate:NewOLM][Skipped:Disconnected] OLMv1 operator installation should install an openshift catalog cluster extension", + "labels": { + "original-name:[sig-olmv1][OCPFeatureGate:NewOLM][Skipped:Disconnected] OLMv1 operator installation should install an openshift catalog cluster extension": {} + }, "resources": { "isolation": {} }, @@ -511,8 +514,11 @@ "environmentSelector": {} }, { - "name": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working validating webhook", - "labels": {}, + "name": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA] OLMv1 operator with webhooks should have a working validating webhook", + "originalName": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working validating webhook", + "labels": { + "original-name:[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working validating webhook": {} + }, "resources": { "isolation": {} }, @@ -521,8 +527,11 @@ "environmentSelector": {} }, { - "name": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working mutating webhook", - "labels": {}, + "name": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA] OLMv1 operator with webhooks should have a working mutating webhook [Serial]", + "originalName": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working mutating webhook", + "labels": { + "original-name:[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working mutating webhook": {} + }, "resources": { "isolation": {} }, @@ -531,8 +540,11 @@ "environmentSelector": {} }, { - "name": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working conversion webhook", - "labels": {}, + "name": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA] OLMv1 operator with webhooks should have a working conversion webhook [Serial]", + "originalName": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working conversion webhook", + "labels": { + "original-name:[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working conversion webhook": {} + }, "resources": { "isolation": {} }, @@ -541,8 +553,11 @@ "environmentSelector": {} }, { - "name": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should be tolerant to tls secret deletion", - "labels": {}, + "name": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA] OLMv1 operator with webhooks should be tolerant to tls secret deletion [Serial]", + "originalName": "[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should be tolerant to tls secret deletion", + "labels": { + "original-name:[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should be tolerant to tls secret deletion": {} + }, "resources": { "isolation": {} }, diff --git a/openshift/tests-extension/Makefile b/openshift/tests-extension/Makefile index 429121f24..429773a3d 100644 --- a/openshift/tests-extension/Makefile +++ b/openshift/tests-extension/Makefile @@ -78,6 +78,17 @@ pkg/bindata/catalog/catalog.go: $(shell find testdata/catalog -type f) mkdir -p $(@D) $(GO_BINDATA) -pkg catalog -o $@ -prefix "testdata/catalog" testdata/catalog/... go fmt ./$(@D)/... +bindata: pkg/bindata/webhook/bundle/bundle.go +pkg/bindata/webhook/bundle/bundle.go: $(shell find testdata/webhook/bundle -type f) + mkdir -p $(@D) + $(GO_BINDATA) -pkg webhookbundle -o $@ -prefix "testdata/webhook/bundle" testdata/webhook/bundle/... + go fmt ./$(@D)/... + +bindata: pkg/bindata/webhook/index/index.go +pkg/bindata/webhook/index/index.go: $(shell find testdata/webhook/index -type f) + mkdir -p $(@D) + $(GO_BINDATA) -pkg webhookindex -o $@ -prefix "testdata/webhook/index" testdata/webhook/index/... + go fmt ./$(@D)/... bindata: pkg/bindata/qe/bindata.go pkg/bindata/qe/bindata.go: $(shell find test/qe/testdata -type f) @@ -110,7 +121,7 @@ update-metadata: #HELP Build and run 'update-metadata' to generate test metadata # How to rename a test? # 1. Run: make list-test-names # 2. Find the current full test name (e.g. "[sig-abc] My test does XYZ") -# 3. Add a Ginkgo label: ginkgo.Label("original-name:[sig-abc] My test does XYZ") +# 3. Add a Ginkgo label: ginkgo.Label("original-name:[sig-abc] My test does XYZ"). if there is existing original-name label, please do not update the label again and keep it unchanged. # 4. Change the test name string and run: make build-update # **Example** # It("should pass a renamed sanity check", diff --git a/openshift/tests-extension/cmd/main.go b/openshift/tests-extension/cmd/main.go index 1b89b4870..f970a2e15 100644 --- a/openshift/tests-extension/cmd/main.go +++ b/openshift/tests-extension/cmd/main.go @@ -8,6 +8,7 @@ https://github.com/openshift-eng/openshift-tests-extension/blob/main/cmd/example */ package main +//nolint:gci // keep import order for readability import ( "fmt" "os" @@ -24,6 +25,7 @@ import ( _ "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/test/qe/specs" exutil "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/test/qe/util" "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/test/qe/util/filters" + "github.com/openshift/origin/test/extended/util/image" ) func main() { @@ -280,6 +282,10 @@ func main() { specs.AddBeforeAll(func() { env.Init() exutil.InitClusterEnv() + // Initialize image repository mapping from KUBE_TEST_REPO environment variable + // This allows tests to work in both connected (repo="") and disconnected (repo=custom) environments + // The KUBE_TEST_REPO variable is set by openshift-tests via --from-repository flag + image.InitializeImages(os.Getenv("KUBE_TEST_REPO")) }) ext.AddSpecs(specs) diff --git a/openshift/tests-extension/go.mod b/openshift/tests-extension/go.mod index cf715d1b6..a16389bcb 100644 --- a/openshift/tests-extension/go.mod +++ b/openshift/tests-extension/go.mod @@ -10,7 +10,7 @@ require ( github.com/openshift-eng/openshift-tests-extension v0.0.0-20250722101414-8083129ab8f9 github.com/openshift/api v0.0.0-20250808142411-c974eeafe3f1 github.com/openshift/client-go v0.0.0-20250710075018-396b36f983ee - github.com/openshift/origin v1.5.0-alpha.3.0.20250927181537-6079513c8d63 + github.com/openshift/origin v1.5.0-alpha.3.0.20251010041851-79ff1dbbe815 github.com/operator-framework/operator-controller v1.5.1 github.com/pborman/uuid v1.2.1 github.com/spf13/cobra v1.10.1 diff --git a/openshift/tests-extension/go.sum b/openshift/tests-extension/go.sum index fdade0bcc..5ec6bf86e 100644 --- a/openshift/tests-extension/go.sum +++ b/openshift/tests-extension/go.sum @@ -201,8 +201,8 @@ github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0 github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20250906192346-6efb6a95323f/go.mod h1:+UmuDIUnxxGlHHQvFhdg4s1XMRX+MBU1n70IYo18IOk= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20250416174521-4eb003743b54 h1:ehXndVZfIk/fo18YJCMJ+6b8HL8tzqjP7yWgchMnfCc= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20250416174521-4eb003743b54/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/openshift/origin v1.5.0-alpha.3.0.20250927181537-6079513c8d63 h1:kt7T98/AlpwFeMZlEqlwRJXWUW0kp9etoZ1uUmZfLnY= -github.com/openshift/origin v1.5.0-alpha.3.0.20250927181537-6079513c8d63/go.mod h1:thiTAaYNKIS7Lh6Lvzwi1JcE/TrX8oSc8u8PfP/Gaa8= +github.com/openshift/origin v1.5.0-alpha.3.0.20251010041851-79ff1dbbe815 h1:Q8fO0DLFlhGKJThi2V+zg8A1acvxj3Cwi+5ZPsY4RsI= +github.com/openshift/origin v1.5.0-alpha.3.0.20251010041851-79ff1dbbe815/go.mod h1:thiTAaYNKIS7Lh6Lvzwi1JcE/TrX8oSc8u8PfP/Gaa8= github.com/operator-framework/operator-controller v1.5.1 h1:J3xdRHzh9ajuKt/i1fWxoOLUf3kMpaOnGf1XNZ6+Klg= github.com/operator-framework/operator-controller v1.5.1/go.mod h1:6BpO9yzrmr1s7zqnk7YUA9SJlNVD+gA25JS5sg6axCE= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= diff --git a/openshift/tests-extension/pkg/bindata/webhook/bundle/bundle.go b/openshift/tests-extension/pkg/bindata/webhook/bundle/bundle.go new file mode 100644 index 000000000..4e428e368 --- /dev/null +++ b/openshift/tests-extension/pkg/bindata/webhook/bundle/bundle.go @@ -0,0 +1,484 @@ +// Code generated for package webhookbundle by go-bindata DO NOT EDIT. (@generated) +// sources: +// testdata/webhook/bundle/Dockerfile +// testdata/webhook/bundle/manifests/webhook-operator-controller-manager-metrics-service_v1_service.yaml +// testdata/webhook/bundle/manifests/webhook-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml +// testdata/webhook/bundle/manifests/webhook-operator-webhook-service_v1_service.yaml +// testdata/webhook/bundle/manifests/webhook-operator-webhooktest-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml +// testdata/webhook/bundle/manifests/webhook-operator-webhooktest-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml +// testdata/webhook/bundle/manifests/webhook-operator-webhooktest-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml +// testdata/webhook/bundle/manifests/webhook-operator.clusterserviceversion.yaml +// testdata/webhook/bundle/manifests/webhook.operators.coreos.io_webhooktests.yaml +// testdata/webhook/bundle/metadata/annotations.yaml +// testdata/webhook/bundle/tests/scorecard/config.yaml +package webhookbundle + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + clErr := gz.Close() + + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + if clErr != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +// Name return file name +func (fi bindataFileInfo) Name() string { + return fi.name +} + +// Size return file size +func (fi bindataFileInfo) Size() int64 { + return fi.size +} + +// Mode return file mode +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} + +// Mode return file modify time +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} + +// IsDir return file whether a directory +func (fi bindataFileInfo) IsDir() bool { + return fi.mode&os.ModeDir != 0 +} + +// Sys return file is sys mode +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _dockerfile = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x92\xc1\x6e\xa3\x40\x0c\x86\xef\x79\x0a\x4b\x7b\x5c\x65\x10\xda\x5c\x39\xec\x46\xdb\x53\xaa\x54\xbd\xf5\x54\x99\xc1\x90\x29\x13\x3c\xf2\x18\x2a\xde\xbe\x82\x00\x6d\xda\x0b\xdc\x06\xc6\xfe\xf8\xb1\xbf\x87\xe7\xf3\x23\x44\x2b\xa8\xf6\xb2\xdb\xfd\x82\x23\x0b\x41\xde\x36\x85\x27\xf0\x98\x93\x8f\x66\x77\xfa\xfb\xef\xff\x09\x38\x90\xa0\xb2\x44\x33\x9f\x4a\xc1\x2b\xbd\xb3\xd4\xc6\xb1\xb9\xf5\x98\x2b\x15\x0e\xb5\x0f\x64\xba\x34\x13\xaa\x5c\x54\xe9\x7f\x77\xe9\x36\x08\x36\xae\xa4\xa8\x71\x80\x2c\x0f\xc9\xc6\x20\x8a\x05\x2a\x8e\x88\xe9\xbc\x8d\x10\xd0\xd6\x58\xdd\xfd\xc8\xa6\x7e\x7b\xc1\xa6\x19\x06\xd8\xa5\x19\xfa\x70\xc1\x75\xdd\x57\x52\x71\x36\x9a\xbc\x75\xbe\x20\xc9\xe6\xa2\x7d\x2c\xea\x7d\x97\x9a\x3f\x07\xb3\x72\x9a\x33\xe9\x6e\x27\xd3\xcb\xd5\x2b\x99\x21\x41\xf8\x8d\xac\xbe\x7a\xec\xb9\xd5\xac\x62\x53\xb7\x39\x4d\x21\x8d\xe3\xa4\x3b\x0c\xfe\x9c\x46\x67\xa0\x64\x01\xa5\xa8\xae\xa9\x56\xfa\x33\x54\xdf\x27\x8d\x96\x85\x2c\x4a\xb1\x3a\xeb\xc8\xb0\xdc\x94\xae\x1a\x00\x3a\x5a\xb3\x60\x92\x9b\xdf\xa1\x87\xd2\x79\x8a\xa0\x0c\x9e\x2d\xaa\xe3\x26\x42\x0c\x64\x5d\xe9\xa8\x80\xbc\x5f\xc4\x3f\x9e\x9f\x5e\x60\xf1\x0f\x92\x2f\x2a\xde\xae\x26\xaf\x20\xf9\x34\x6c\xbc\xf8\xf6\x65\x48\x7e\x44\xf9\x08\x00\x00\xff\xff\xa9\xb8\xee\xcf\x78\x03\x00\x00") + +func dockerfileBytes() ([]byte, error) { + return bindataRead( + _dockerfile, + "Dockerfile", + ) +} + +func dockerfile() (*asset, error) { + bytes, err := dockerfileBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "Dockerfile", size: 888, mode: os.FileMode(420), modTime: time.Unix(1760064351, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _manifestsWebhookOperatorControllerManagerMetricsService_v1_serviceYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x90\xc1\x4a\x03\x31\x10\x86\xef\xfb\x14\xf3\x02\xa9\x88\x3d\x48\x8e\xfa\x02\x05\x8b\xf7\xd9\xec\x4f\x1b\x36\xc9\x84\xc9\x6c\x45\xc5\x77\x97\x4d\x2b\x08\xda\x53\x8f\x7f\xf2\x25\xf3\x7f\xc3\x35\xbe\x42\x5b\x94\xe2\xe9\x74\x3f\xcc\xb1\x4c\x9e\x5e\xa0\xa7\x18\x30\x64\x18\x4f\x6c\xec\x07\xa2\xa0\x60\x8b\x52\xf6\x31\xa3\x19\xe7\xea\xa9\x2c\x29\x0d\x44\x89\x47\xa4\xb6\x32\x44\x5c\xeb\x66\x5e\x46\x68\x81\xa1\x6d\xa2\xdc\x65\x2e\x7c\xc0\xe4\xc6\x77\x4f\xf3\xd2\x4c\x72\xfc\xc0\x15\xb6\x70\x86\xa7\x37\x8c\x47\x91\xd9\x49\x85\xb2\x89\x76\x38\x48\x31\x95\xe4\x6a\xe2\x02\xff\x13\x13\xd4\x9d\x07\xac\xd4\xff\xcf\xdd\x5f\xd6\x65\x98\xc6\xd0\x5c\xbb\x88\xb6\x8a\xb0\x0a\x54\x51\xeb\x26\xee\xf2\xd9\xd1\xac\xb6\x5e\x60\xbd\xf2\xf4\xb8\xdd\x3e\x9c\xa3\x8a\x49\x90\xe4\x69\xff\xbc\xeb\x27\xc6\x7a\x80\xed\x7e\x63\x0d\x09\xc1\x44\xaf\xed\xe6\x26\xdf\x66\x6c\x4b\x2f\x9b\x84\xa7\x27\x4e\x5c\x02\xd4\xd3\xe7\xd7\xf0\x1d\x00\x00\xff\xff\xc9\x7d\x34\x2a\xd5\x01\x00\x00") + +func manifestsWebhookOperatorControllerManagerMetricsService_v1_serviceYamlBytes() ([]byte, error) { + return bindataRead( + _manifestsWebhookOperatorControllerManagerMetricsService_v1_serviceYaml, + "manifests/webhook-operator-controller-manager-metrics-service_v1_service.yaml", + ) +} + +func manifestsWebhookOperatorControllerManagerMetricsService_v1_serviceYaml() (*asset, error) { + bytes, err := manifestsWebhookOperatorControllerManagerMetricsService_v1_serviceYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "manifests/webhook-operator-controller-manager-metrics-service_v1_service.yaml", size: 469, mode: os.FileMode(420), modTime: time.Unix(1760064210, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _manifestsWebhookOperatorMetricsReader_rbacAuthorizationK8sIo_v1_clusterroleYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\x8c\xb1\x4e\xc4\x30\x10\x05\x7b\x7f\xc5\xfe\x80\x73\xa2\x43\x6e\x69\xa9\x22\xa0\xdf\x38\x4f\xdc\x2a\xb6\x37\xda\x5d\x1f\x12\x5f\x8f\x38\xa5\x1d\xcd\x0c\x9f\xf2\x05\x73\xd1\x51\xc8\x36\xae\x0b\xcf\xb8\xab\xc9\x2f\x87\xe8\x58\x8e\x57\x5f\x44\x6f\x8f\x97\x74\xc8\xd8\x0b\xbd\xb5\xe9\x01\x5b\xb5\x21\x75\x04\xef\x1c\x5c\x12\x51\x35\x3c\x83\x0f\xe9\xf0\xe0\x7e\x16\x1a\xb3\xb5\x44\x34\xb8\xa3\xd0\x0f\xb6\xbb\xea\x91\xf5\x84\x71\xa8\xe5\x8e\x30\xa9\x9e\x0d\xbc\xc3\x92\xcd\x06\x2f\x29\xd3\xd0\xb1\xc2\x75\x5a\xc5\xe7\xfa\xee\xff\xef\x4c\xb7\xcb\x4e\x44\x0f\xd8\x76\xd1\x6f\x44\xfa\x0b\x00\x00\xff\xff\x92\x4d\xeb\x0f\xbf\x00\x00\x00") + +func manifestsWebhookOperatorMetricsReader_rbacAuthorizationK8sIo_v1_clusterroleYamlBytes() ([]byte, error) { + return bindataRead( + _manifestsWebhookOperatorMetricsReader_rbacAuthorizationK8sIo_v1_clusterroleYaml, + "manifests/webhook-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml", + ) +} + +func manifestsWebhookOperatorMetricsReader_rbacAuthorizationK8sIo_v1_clusterroleYaml() (*asset, error) { + bytes, err := manifestsWebhookOperatorMetricsReader_rbacAuthorizationK8sIo_v1_clusterroleYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "manifests/webhook-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml", size: 191, mode: os.FileMode(420), modTime: time.Unix(1760064210, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _manifestsWebhookOperatorWebhookService_v1_serviceYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x90\x41\x4e\x03\x31\x0c\x45\xf7\x39\x85\x2f\x90\x22\x44\x37\x64\x09\x17\xa8\x44\xc5\xde\x93\xf9\x2a\xd1\x24\x71\xe4\x78\x8a\x00\x71\x77\xd4\x94\xee\x3a\x3b\xfb\xfb\x49\x7e\x36\xb7\xf4\x0e\xed\x49\x6a\xa0\xf3\xa3\x5b\x52\x9d\x03\xbd\x41\xcf\x29\xc2\x15\x18\xcf\x6c\x1c\x1c\x51\x54\xb0\x25\xa9\xc7\x54\xd0\x8d\x4b\x0b\x54\xd7\x9c\x1d\x51\xe6\x09\xb9\x5f\x18\x22\x6e\x6d\xb7\xac\x13\xb4\xc2\xd0\x77\x49\x1e\x0a\x57\x3e\x61\xf6\xd3\x57\xa0\x65\xed\x26\x25\x7d\x63\x83\xad\x5c\x10\xe8\x13\xd3\x87\xc8\xe2\xa5\x41\xd9\x44\x1d\xd1\xfd\x81\xbf\x05\xfd\xdf\xb7\x37\xc4\x8b\x47\x13\xb5\x21\xe4\x47\x19\x68\xbf\x7f\x1a\x2b\x9b\x8a\x49\x94\x1c\xe8\xf8\x7a\x18\x89\xb1\x9e\x60\x87\x41\x3d\x5f\xb1\x8e\x8c\x68\xa2\x5b\x17\x6d\x5a\x12\x45\xa9\xa6\x92\x7d\xcb\x5c\x11\x6e\x6d\x86\xfa\xeb\x1b\xd4\x75\x63\x5b\x87\x5b\x16\x9e\x5f\x38\x73\x8d\xd0\x40\x3f\xbf\xee\x2f\x00\x00\xff\xff\x1c\x22\x97\x76\x8b\x01\x00\x00") + +func manifestsWebhookOperatorWebhookService_v1_serviceYamlBytes() ([]byte, error) { + return bindataRead( + _manifestsWebhookOperatorWebhookService_v1_serviceYaml, + "manifests/webhook-operator-webhook-service_v1_service.yaml", + ) +} + +func manifestsWebhookOperatorWebhookService_v1_serviceYaml() (*asset, error) { + bytes, err := manifestsWebhookOperatorWebhookService_v1_serviceYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "manifests/webhook-operator-webhook-service_v1_service.yaml", size: 395, mode: os.FileMode(420), modTime: time.Unix(1760064210, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _manifestsWebhookOperatorWebhooktestAdminRole_rbacAuthorizationK8sIo_v1_clusterroleYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x8e\xbd\x4e\x43\x31\x0c\x85\xf7\x3c\x85\xb7\x4a\x48\x49\xc5\x86\xb2\x32\xb0\x23\xc4\xee\xdc\x6b\xb5\x51\x7e\x1c\xd9\x4e\x11\x7d\x7a\x74\xaf\xda\x01\x04\x1b\xab\x7d\xbe\xef\x1c\x1c\xf9\x9d\x44\x33\xf7\x08\x92\x70\x09\x38\xed\xcc\x92\xaf\x68\x99\x7b\x28\x4f\x1a\x32\x1f\x2f\x8f\xae\xe4\xbe\x46\x78\xae\x53\x8d\xe4\x95\x2b\xb9\x46\x86\x2b\x1a\x46\x07\xb0\x08\xed\xc0\x5b\x6e\xa4\x86\x6d\x44\xe8\xb3\x56\x07\x50\x31\x51\xd5\x2d\x03\x80\x63\x84\x32\x13\x49\x27\xa3\x5d\xdc\xb0\xe3\x89\x56\x9f\x3e\x23\x94\xa9\xc6\x2d\x5f\xe9\x8f\x6c\xc7\x46\x11\x3e\x28\x9d\x99\x8b\xe7\x41\x82\xc6\xe2\x00\x7e\x7f\xf8\xdb\xc1\x48\xcd\xe3\xda\x72\xf7\xb2\xcd\x96\x59\x49\xa3\xf3\x80\x23\xbf\x08\xcf\xb1\x8f\xf3\x77\x3e\xdc\x79\x0d\x0b\x0b\xf1\x56\xed\x00\x84\x94\xa7\x2c\xf4\x3d\xbc\xb9\xd5\x01\x5c\x48\xd2\xed\x73\x78\x38\xfc\xa3\xfb\xa8\x86\x36\x7f\x54\x9c\xc8\xdc\x57\x00\x00\x00\xff\xff\x8c\x9c\xc7\xde\xb8\x01\x00\x00") + +func manifestsWebhookOperatorWebhooktestAdminRole_rbacAuthorizationK8sIo_v1_clusterroleYamlBytes() ([]byte, error) { + return bindataRead( + _manifestsWebhookOperatorWebhooktestAdminRole_rbacAuthorizationK8sIo_v1_clusterroleYaml, + "manifests/webhook-operator-webhooktest-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml", + ) +} + +func manifestsWebhookOperatorWebhooktestAdminRole_rbacAuthorizationK8sIo_v1_clusterroleYaml() (*asset, error) { + bytes, err := manifestsWebhookOperatorWebhooktestAdminRole_rbacAuthorizationK8sIo_v1_clusterroleYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "manifests/webhook-operator-webhooktest-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml", size: 440, mode: os.FileMode(420), modTime: time.Unix(1760064210, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _manifestsWebhookOperatorWebhooktestEditorRole_rbacAuthorizationK8sIo_v1_clusterroleYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x90\xb1\x6e\xf3\x30\x0c\x84\x77\x3d\x05\x5f\xc0\x0e\xfe\xed\x87\xd6\x0e\xdd\x8b\xa2\x3b\x6d\x1f\x12\xc1\xb2\x28\x90\x54\x82\xe6\xe9\x0b\xab\xf1\xd0\xa2\xdd\x3a\xe9\x70\x3c\x9e\x3e\x90\x6b\x7a\x83\x5a\x92\x12\x49\x27\x9e\x47\x6e\x7e\x11\x4d\x77\xf6\x24\x65\x5c\xff\xdb\x98\xe4\x74\xfd\x17\xd6\x54\x96\x48\x4f\xb9\x99\x43\x5f\x24\x23\x6c\x70\x5e\xd8\x39\x06\xa2\x59\xd1\x17\x5e\xd3\x06\x73\xde\x6a\xa4\xd2\x72\x0e\x44\x99\x27\x64\xdb\x33\x44\x5c\xeb\xb8\xb6\x09\x5a\xe0\xe8\xc5\x1b\x17\x3e\x63\x19\xa6\xf7\x48\x6b\x33\x97\x2d\xdd\xf1\x4b\xb6\xf0\x86\x48\x37\x4c\x17\x91\x75\x90\x0a\x65\x17\x0d\x44\x3f\x0f\x86\x87\xe1\x30\x1f\xb0\xa4\xdd\xd2\x9d\x5b\x5b\x86\xc5\x30\x10\xd7\xf4\xac\xd2\x6a\xa7\x1b\x8e\x82\xf1\x28\xb0\x71\x16\x85\xec\x7f\x07\x22\x85\x49\xd3\x19\x5f\xc3\x7b\xb9\x05\xa2\x2b\x74\x7a\x4c\xfa\x29\xd0\xe5\x82\x8c\x87\x3c\xc3\xfb\x9b\x93\x7d\x8a\xca\x3e\x5f\xba\x6a\x75\x39\x16\x6e\xdd\xfc\x3b\xb2\x93\x39\x7b\xfb\x06\xb8\xa3\x7c\x04\x00\x00\xff\xff\xef\x37\x19\xc6\xf7\x01\x00\x00") + +func manifestsWebhookOperatorWebhooktestEditorRole_rbacAuthorizationK8sIo_v1_clusterroleYamlBytes() ([]byte, error) { + return bindataRead( + _manifestsWebhookOperatorWebhooktestEditorRole_rbacAuthorizationK8sIo_v1_clusterroleYaml, + "manifests/webhook-operator-webhooktest-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml", + ) +} + +func manifestsWebhookOperatorWebhooktestEditorRole_rbacAuthorizationK8sIo_v1_clusterroleYaml() (*asset, error) { + bytes, err := manifestsWebhookOperatorWebhooktestEditorRole_rbacAuthorizationK8sIo_v1_clusterroleYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "manifests/webhook-operator-webhooktest-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml", size: 503, mode: os.FileMode(420), modTime: time.Unix(1760064210, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _manifestsWebhookOperatorWebhooktestViewerRole_rbacAuthorizationK8sIo_v1_clusterroleYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x8e\xb1\x6e\xf3\x30\x0c\x84\x77\x3d\x05\x5f\x40\x0e\xfe\xed\x87\xd6\x0e\xdd\x8b\xa2\x3b\xed\x1c\x12\xc1\x92\x28\x90\x54\x82\xe6\xe9\x0b\xbb\xc9\x50\x20\xdd\x3a\x91\xe0\x1d\xbf\x3b\xee\xf9\x03\x6a\x59\x5a\x22\x9d\x79\x99\x78\xf8\x59\x34\xdf\xd8\xb3\xb4\x69\xfd\x6f\x53\x96\xc3\xe5\x5f\x58\x73\x3b\x26\x7a\x29\xc3\x1c\xfa\x26\x05\xa1\xc2\xf9\xc8\xce\x29\x10\x2d\x8a\xfd\xe1\x3d\x57\x98\x73\xed\x89\xda\x28\x25\x10\x15\x9e\x51\x6c\xf3\x10\x71\xef\xd3\x3a\x66\x68\x83\x63\x07\x57\x6e\x7c\xc2\x31\xce\x9f\x89\xd6\x61\x2e\x35\xdf\xf0\x8b\xb7\x71\x45\xa2\x2b\xe6\xb3\xc8\x1a\xa5\x43\xd9\x45\x03\xd1\x73\x21\xde\x0f\x0e\xf3\x78\xc9\xb8\x42\xa3\x6e\xbd\x75\x14\x58\x0a\x91\xb8\xe7\x57\x95\xd1\xf7\x76\xf1\x01\x98\x1e\x00\x9b\x16\x51\xc8\x96\x1d\x88\x14\x26\x43\x17\xfc\x34\x6f\x70\x0b\x44\x17\xe8\x7c\x57\x4e\xf0\x7d\x96\x6c\xdf\xcb\x95\x7d\x39\xff\x61\xdc\xc1\x9c\x7d\x3c\x49\xfd\x0a\x00\x00\xff\xff\x53\xe3\xf7\xd0\xcc\x01\x00\x00") + +func manifestsWebhookOperatorWebhooktestViewerRole_rbacAuthorizationK8sIo_v1_clusterroleYamlBytes() ([]byte, error) { + return bindataRead( + _manifestsWebhookOperatorWebhooktestViewerRole_rbacAuthorizationK8sIo_v1_clusterroleYaml, + "manifests/webhook-operator-webhooktest-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml", + ) +} + +func manifestsWebhookOperatorWebhooktestViewerRole_rbacAuthorizationK8sIo_v1_clusterroleYaml() (*asset, error) { + bytes, err := manifestsWebhookOperatorWebhooktestViewerRole_rbacAuthorizationK8sIo_v1_clusterroleYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "manifests/webhook-operator-webhooktest-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml", size: 460, mode: os.FileMode(420), modTime: time.Unix(1760064210, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _manifestsWebhookOperatorClusterserviceversionYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x59\x5f\x6f\xe3\xb8\x11\x7f\xf7\xa7\x18\xf8\xb9\xb2\xe3\x6d\xf6\x90\x0a\x38\xa0\x69\x36\xb7\x38\x20\x7f\x8c\x24\xbd\x3e\x14\x45\x41\x93\x63\x9b\x35\xff\xa8\x24\xa5\xac\x77\xbb\xdf\xbd\x20\x29\xc9\x96\x2c\x29\x76\x12\xb4\x68\xef\xf4\x62\x5b\x9c\xe1\xcc\xfc\x66\x38\x9c\x19\x93\x8c\xff\x82\xc6\x72\xad\x52\xd0\x19\x1a\xe2\xb4\xb1\x13\xaa\x0d\x6a\xff\x21\xa7\xc5\x8c\x88\x6c\x4d\x66\xa3\x0d\x57\x2c\x85\x2b\x91\x5b\x87\xe6\x11\x4d\xc1\x29\x96\xac\x23\x89\x8e\x30\xe2\x48\x3a\x02\x20\x4a\x69\x47\x1c\xd7\xca\xfa\x9f\x00\x44\xc8\x04\xbf\x10\x99\x09\xb4\x29\xfc\x2b\x09\x2f\x01\xfe\x5a\x7e\x02\x7c\xab\xbf\x01\x8c\x77\x0a\x8d\x53\x18\x3f\xe3\x62\xad\xf5\x66\x72\xa0\x1a\xd7\xd3\x62\x36\xfe\xdd\x3e\xa7\x57\xd0\xf3\xfc\x25\xf2\x3c\xa1\x75\x4d\x82\x4a\xcb\x71\xda\x10\x09\x30\x16\x64\x81\xc2\x1e\xbc\x0f\xea\x64\x93\x4d\xbe\x40\xa3\xd0\x61\x10\x2b\x89\x22\x2b\x64\xc9\x62\xeb\x85\x6d\x72\xeb\xb4\xe4\x5f\xb1\x21\xaa\x87\x55\x11\x89\x7b\x56\x25\x95\x55\xe3\x06\xeb\xf7\xe6\x4e\xe3\x16\x97\x43\xeb\x12\x1b\xe0\xdc\xe7\x6b\x70\x8d\x6d\x86\x74\x9c\x82\xca\x85\x18\x75\x50\xbc\x16\xf1\x0f\xbf\x21\x7e\x12\xe2\xe5\xb7\xbf\x85\x4f\x4a\x32\xb2\xe0\x82\x3b\xee\xcf\xc1\x9f\x88\xe5\x14\x7e\x56\xd6\x91\x92\x63\x87\x78\xf5\x6d\x69\x88\xc4\x67\x6d\x36\xde\x94\x45\xce\x05\x43\xb3\x3b\xa6\x89\x65\x9b\xa4\x98\x4d\xce\x67\x93\xd9\x31\x1b\x64\x46\xff\x03\xa9\xfb\xbb\x20\x5b\x9d\xbb\x14\x56\x3a\x80\x55\xee\x1b\xfc\x7b\x3e\x02\xf0\xc6\xa7\xd0\x06\x6c\x52\x9c\x4d\xce\x26\x1f\xcb\x75\x9b\x11\x8a\x29\x64\x82\x50\x5c\x6b\xcf\x3e\xf2\xf6\x87\xe3\x9f\x71\x1b\x93\x03\xc3\x25\x57\x3c\x26\x02\xf8\xe6\xb1\xa0\xc1\x75\x06\xad\xce\x4d\x73\x3d\xea\xff\xac\x90\xa5\x25\x66\x09\x30\xb4\xd4\xf0\xcc\x85\xdc\xb4\x17\x62\xc0\x2d\xb8\x35\xc2\x23\x5d\xa3\x24\xb0\xd4\x26\xfc\xdc\x73\x96\x85\xcb\xf9\xcf\xb5\x17\x18\xb7\x99\x20\xdb\xbb\x60\x57\xb9\x0f\xf8\x8d\x6a\x8a\x98\xda\xf6\x44\xd4\x2b\x0d\x30\xc2\xd6\x93\x81\x03\x52\xb3\x15\x55\x4a\x2d\x66\xff\x5f\xe6\x7c\x18\x41\xd3\x90\x76\x9c\x80\xdf\x15\x96\xfc\x8b\xcb\x0d\x8e\x5a\xda\xb6\x89\x47\x00\x9c\x6a\x15\x5d\x9e\xc0\x82\x58\xfc\xe1\x3c\xdc\x23\x30\xae\x4e\x9a\x44\xc6\x89\xdb\x66\x58\xbe\xe3\xf1\xc4\x44\x9e\x2a\xe8\xc2\xf1\x8a\x37\xd3\x1c\x8d\xe4\xd6\xee\xa2\x2a\xee\x6d\x72\x7f\xfb\x34\x8e\x79\xe2\x63\xf5\xb3\xd1\x79\xd6\x5a\x88\x8b\xc7\x00\x13\x9f\x2a\xa0\x87\xb6\x09\x60\xb7\x96\x0b\x34\x8b\x4e\x1e\x6a\x90\x38\xec\x58\x60\x28\xb0\x73\x61\x85\xae\xe3\xad\xe0\xb6\xeb\x75\x46\x1c\x5d\x77\xbc\xcf\x33\xd6\x2d\xf6\xf9\x80\xe1\x3f\x8f\xdd\x74\xc9\x15\x11\xfc\x2b\x9a\xa3\x61\xec\xb0\xe7\xbf\xa0\xb7\x75\xc4\xe5\x47\xeb\xdc\xed\xc8\x13\x3c\xf6\x82\x85\x24\x77\x6b\x54\x8e\xd3\x50\xa1\x4d\x36\x17\xa7\xda\xe6\xf4\x06\x95\xc1\x82\xe3\xf3\x5b\xe2\xf9\x08\x35\xb5\xe1\x5f\x5f\xab\xa5\xcd\x17\xfe\xae\x23\x94\xa2\xb5\x6f\xd5\xb6\xbc\xcf\x2e\x29\xd5\xb9\x72\xdd\xa9\x2c\xa1\x5a\x39\xa3\x85\x40\x93\xc4\x7a\xc5\x94\x3b\x30\xcc\x84\xde\x4a\x54\xae\x91\x90\x42\x01\xd4\x14\x3f\x54\xf9\xa4\x50\xd7\x3d\x2f\xf0\x74\xdf\xdf\x0d\xa6\x52\xd7\x24\x13\x44\x61\x0a\xbd\xaa\x43\xfb\xca\x38\xc2\x5c\x68\xa5\xe5\xca\x59\x99\xe0\x94\xd8\x14\x66\x8d\xf7\x16\x05\x52\xa7\x4d\xdb\x0f\xd2\x07\xfc\x4d\xa8\x11\x0f\x5d\xf4\x2a\x9b\x4f\xb5\x1b\xc0\x3a\x43\x1c\xae\xb6\x65\xf1\xb2\x7b\x1c\xca\x4c\x10\x87\x07\x4a\xef\x75\x41\x2d\x8d\xdb\x3d\x51\xf3\xf1\xc6\x50\x27\x5a\x46\x31\x5c\x92\x5c\xb8\x00\x35\xe1\xca\x97\x7e\x5d\x6a\xfa\x47\xf4\x20\xf5\x06\xac\x4e\x45\xab\xcb\xeb\xd5\x2e\x41\xfb\x4e\xf5\x12\x20\x66\xd5\xb9\x12\x57\x93\x44\xa2\x33\x9c\xda\x64\xc1\x15\x4b\x08\x63\x06\xad\xfd\x31\xbd\x38\x3f\xff\xfd\x00\x93\x40\xc2\xd0\x24\x21\xb8\x06\xc8\xd6\x48\x84\x5b\x27\x99\xd1\x0b\x6c\x0b\x38\xbb\x98\x0d\x70\x56\xf0\x51\x34\x2e\xc9\x88\x5b\xff\x38\x75\x32\x9b\x6e\x2e\x6c\xbd\xe4\xb3\x06\x9a\x69\x48\x1e\x6a\x15\x28\xdb\x29\xa8\x42\x48\x4a\xa2\x58\x3f\x08\xd3\x3e\xb7\xfb\x87\x4b\xb2\xf2\xb5\xd1\xb7\x6f\xf0\x74\xfd\xf8\x94\x5c\xdd\xdf\x3d\x3d\xdc\xdf\xdc\x5c\x3f\xc0\xf7\xef\xe3\x4e\x16\xc1\x0b\x54\x68\xed\xdc\xdb\xdd\x27\x76\xed\x5c\xf6\x19\x5d\xdf\x32\xf8\x3b\x69\x9d\xc2\x34\x62\xf8\xb5\x9f\x4c\x1b\x97\xc2\x00\x9c\xa1\x07\x20\xe2\x13\x0a\xb2\x7d\x44\xaa\x15\xf3\x59\xe2\x63\x0f\x75\x86\x86\x6b\x56\xd3\x7d\x38\xeb\xa4\x8b\x31\x3e\x04\x9b\x57\x6b\x20\xee\xea\xa8\x9d\x07\xf5\xff\xd0\x1f\x6e\xed\x0c\x19\xdd\xde\x0f\x87\xd1\x4e\x53\x2d\x52\x78\xba\x9a\x77\x52\x19\x24\x8c\xbf\x9b\x7b\xfc\x6e\xdb\xf7\xf6\xce\x91\xce\x99\x75\x3b\x67\xe0\xe2\x8e\x8f\xe0\x92\xf7\x3b\x07\x80\x66\x79\x0a\x1f\xcf\xce\x64\x2f\x85\x44\xa9\xcd\x36\x85\xd9\x87\x8b\x5b\xde\x43\x65\xf0\x9f\xb9\x2f\xd0\x5e\x90\x33\x3b\x42\xcc\x0f\xe7\x3d\x52\x2c\xd2\xdc\x70\xb7\xbd\xd2\xca\xe1\x97\x5e\x6f\x11\x21\xf4\xf3\xdc\xf0\x82\x0b\x5c\xe1\xb5\xa5\x44\x90\xd8\x5e\x2d\x89\xb0\x87\x15\x79\xa9\xde\xfe\x3c\xa1\x57\x47\x66\x74\xd6\xbf\xea\x63\xfd\xf2\xe6\xa6\x17\x22\xc2\xee\x95\xd8\x3e\x68\xed\x7e\xe2\x02\xed\xd6\x3a\x94\x29\x38\x93\x77\x2b\x55\x68\x91\x4b\xbc\xf5\x65\xd2\xc0\xe1\x92\x7e\x7d\x1e\xe3\xf3\xd5\x59\x13\x0e\x4e\xde\x30\x6d\x65\x4b\x8f\xf6\x47\x78\xca\xe4\xea\xd2\xde\x69\xe5\xd1\xe8\xc5\xc0\x22\xa5\x5a\x66\x73\xa3\x97\x5c\xf4\x9c\xde\xd8\xcd\x3e\xe4\xca\x71\x89\x9f\xe2\x2d\xdf\xa1\xd0\x5b\x8a\xce\x3d\x61\xbe\x1f\x56\x21\x9c\x3e\x1b\x42\x71\xfe\xe2\x19\x8d\x4e\xec\xb9\xae\x8f\x85\xdc\x22\x35\xfd\xe9\x29\xae\xde\x75\x24\xce\xb0\x65\xc9\x95\xbd\x57\x2b\x3f\x6e\xdf\x83\x83\xbd\x03\xd5\x6a\xc9\x57\x92\x64\x6f\x6c\xda\x7a\xba\xef\xc3\x66\x1a\x86\x9b\xfe\xde\xb6\xbc\xaf\x2b\xec\x98\x12\xbc\x00\x10\xd5\xda\xb0\x32\x4a\x5e\xd1\x6d\x09\x24\x16\x7f\x3d\x68\x9d\x16\x4e\x58\xf8\xd6\xef\x0d\xad\x72\xb7\xfa\x6f\xc9\x0f\xbb\xce\x66\xd7\x9c\xee\x46\x6b\xb7\x9a\x55\x96\xf8\x46\x3a\xf3\x35\x02\xb2\xe6\x5d\x14\x53\xd8\xfd\xb3\xba\xab\xa6\xc1\xc7\xd0\x3f\x72\xb5\x12\x78\x12\xcb\x6d\x2e\x1c\x1f\xe0\xd8\x4b\xc3\x91\xe1\x52\x88\x9a\xdc\xa3\xbe\xc1\xed\xb3\x36\xac\x36\xc8\x55\xf3\xd0\x04\x1a\xbd\x4f\x3d\xb5\xf1\x4c\x82\xab\x4d\xcd\xa1\x1a\x93\xd6\xfb\x66\xc3\x94\x1b\x91\x86\x62\xcc\xa6\xd3\xe9\xc1\xd0\x9c\x69\x49\xb8\x1a\xf9\x7e\x96\x37\xdb\xa0\x04\x50\x12\x2e\x52\x50\x3a\xf1\xcd\xf1\xf6\x8f\xb5\xd3\xf6\x87\xf6\xa5\x94\xa8\x42\x45\x1a\xf6\x73\xe1\xba\x4a\x21\xfc\x3b\x37\x0a\x85\x65\xc1\x19\x96\x9d\x74\x64\x38\xdc\x72\xb4\x37\xcc\xad\x06\xfa\xa5\xd6\x07\xe3\xf8\x04\x08\x2b\xf3\xef\x43\x98\xa0\x94\xff\x12\x35\x92\x71\x3d\xe0\x6e\x55\xcc\xbb\x82\x99\x6a\x55\x8a\xbc\x7a\xf8\xd4\xe0\x3d\x71\x0e\xbd\x8b\xd5\x53\x6f\xc3\x15\x2a\x4f\x82\x91\x8f\x36\xe4\x6e\x16\x3b\x09\x96\x33\xbc\x5e\x2e\x91\x3a\x9b\xc2\x9d\x56\x75\x64\x11\xb3\x42\x77\xd0\x0a\xc4\x80\xbb\xaa\xed\x2b\x43\xa4\x5c\x2d\xa5\x94\x75\x4e\x44\xc1\xbd\x27\xb0\xaf\xc7\x63\x49\xb8\xc8\x0d\xce\xb5\xe0\x74\x9b\xc2\x4f\x84\x8b\x4e\xa4\xe4\xfe\x1f\x60\xc5\xac\x81\x55\xeb\x16\xee\x4d\x99\xc7\x0e\x55\x77\xff\x42\x1e\x6c\x50\xec\x37\x27\x71\x97\x2e\xb2\xab\x87\xeb\xcb\xa7\xeb\xd6\xcb\x3f\xcf\x3f\x35\x5f\xf6\xe4\xea\xce\x41\xfd\xab\xe2\xe1\x36\x77\xc4\x71\xb5\xba\xac\x7c\x3c\x14\x16\xd2\x13\x63\xd2\x76\x9d\x4d\x22\x44\x09\xd7\x49\x31\x4b\xf6\x54\xfb\xdf\x0a\xa0\xe2\xb7\x00\x3a\x3d\x80\x7e\x21\x82\xb3\xe3\x43\xa8\x88\xe4\x27\x05\xd1\xbf\x03\x00\x00\xff\xff\xc1\xbf\x66\x76\xf6\x21\x00\x00") + +func manifestsWebhookOperatorClusterserviceversionYamlBytes() ([]byte, error) { + return bindataRead( + _manifestsWebhookOperatorClusterserviceversionYaml, + "manifests/webhook-operator.clusterserviceversion.yaml", + ) +} + +func manifestsWebhookOperatorClusterserviceversionYaml() (*asset, error) { + bytes, err := manifestsWebhookOperatorClusterserviceversionYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "manifests/webhook-operator.clusterserviceversion.yaml", size: 8694, mode: os.FileMode(420), modTime: time.Unix(1760064904, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _manifestsWebhookOperatorsCoreosIo_webhooktestsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\xdd\x6f\xdc\xc6\x11\x7f\xbf\xbf\x62\xa0\x16\xa8\x65\x88\x3c\xcb\x29\xdc\xf8\x5e\x0c\x43\x71\x0a\xa3\x49\x60\xd8\xaa\x0b\x54\x55\x83\x39\x72\xc8\xdb\x8a\xdc\x65\xf6\xe3\xa4\x4b\xdb\xff\xbd\x98\xdd\xe5\x91\xc7\x23\x25\x59\x46\xf3\xc4\x7d\x12\xf7\x63\x66\x76\x3e\x7e\x33\x3b\x3a\x6c\xc4\x67\xd2\x46\x28\xb9\x02\x6c\x04\xdd\x59\x92\xfc\x65\xd2\x9b\x6f\x4d\x2a\xd4\x72\x7b\xbe\xb8\x11\x32\x5f\xc1\x85\x33\x56\xd5\x1f\xc9\x28\xa7\x33\xfa\x8e\x0a\x21\x85\x15\x4a\x2e\x6a\xb2\x98\xa3\xc5\xd5\x02\x00\xa5\x54\x16\x79\xda\xf0\x27\x40\x46\xda\x26\x35\x4a\x2c\x49\x33\x39\x21\xff\x45\x99\x4d\x32\x4c\x0a\xad\xea\x15\xdc\xd2\x7a\xa3\xd4\x4d\xa2\x1a\xd2\x68\x95\x4e\xcc\xce\x58\xaa\x97\xc7\xf3\xa4\xb7\x42\x96\x09\x13\x0c\x94\x95\xb4\x5a\x55\x15\xe9\xa4\x24\x99\xde\xb8\x35\xad\x9d\xa8\xf2\xc0\x67\xdb\x5e\x6a\xfb\x22\x3d\x7f\x9d\xbe\x58\x00\x64\x9a\xbc\x64\x97\xa2\x26\x63\xb1\x6e\x56\x20\x5d\x55\x2d\x00\x24\xd6\xb4\x17\xc5\x92\xb1\x26\x8d\x1f\x69\xcb\xdf\xa4\x99\xd2\xa4\x58\x25\x0b\xd3\x50\xc6\xb7\xcb\x94\x6c\xd9\x78\x89\x8c\xd5\x68\xa9\xdc\xad\xe0\x6f\xe1\xb4\x9f\x8d\x94\xc2\x16\x80\xac\x12\x24\xed\x85\x92\x85\x28\xdb\x39\x00\x7f\xbb\x8c\xba\x89\x81\x50\x9d\x1e\xda\x89\x78\x62\x70\xc0\x34\x98\x8d\x9d\x0a\x5a\xed\x6d\x6e\xd0\x6e\x56\xb0\x0c\x57\xb0\xad\x6c\xfb\x0b\x7d\xa4\xad\xa0\xdb\xe8\x19\xa6\x15\x2b\x81\xed\xf9\x02\xa0\xd4\xca\x35\x7b\x26\xa3\x2a\x8a\xd2\x84\x83\xc1\x7f\xa2\x4e\x2e\xc9\x04\x76\x95\x30\xf6\x2f\xc3\x95\x1f\x44\x5c\x6d\x2a\xa7\xb1\x3a\x34\x4a\x50\xb2\x90\xa5\xab\x50\x1f\x2c\x2d\x00\x4c\xa6\x1a\x5a\xc1\x4f\xad\x12\xf2\x05\xc0\xb6\x27\x7f\x12\x15\xea\x6f\xc0\xdb\x37\x54\x63\x7b\x31\xd5\x90\x7c\xfb\xe1\xfd\xe7\x6f\x3e\x1d\x4c\x03\xe4\x64\x32\x2d\x1a\xeb\x5d\xa9\x27\x27\x08\x03\x76\x43\x10\xf6\x43\xa1\xb4\xff\xec\x4b\x0b\x6f\x3f\xbc\xdf\xd3\x69\x34\x6b\xc9\x0a\x32\x7d\x13\xf7\x82\xaf\x37\x3b\xe0\xfa\x9f\xe4\x60\x0d\x98\x6e\x3c\x05\x39\x47\x21\x05\x51\xe2\x65\x29\x8f\x77\x03\x55\x80\xdd\x08\x03\x9a\x1a\x4d\x86\x64\x88\x4b\x9e\x46\x09\x6a\xcd\x71\x98\x0e\x48\x7f\x22\xcd\x64\xc0\x6c\x94\xab\xf2\xe8\x0f\x16\x34\x65\xaa\x94\xe2\xd7\x3d\x6d\x03\x56\x79\xa6\x15\x5a\xaf\x0d\x69\x49\x4b\xac\x60\x8b\x95\xa3\x33\x40\x99\x0f\x28\xd7\xb8\x03\x4d\xcc\x13\x9c\xec\xd1\xf3\x07\xcc\x50\x8e\x1f\x95\x26\x10\xb2\x50\x2b\xd8\x58\xdb\x98\xd5\x72\x59\x0a\xdb\x42\x52\xa6\xea\xda\x49\x61\x77\x4b\x8f\x01\x62\xed\xd8\xfb\x96\x39\x6d\xa9\x5a\x1a\x51\x26\xa8\xb3\x8d\xb0\x94\x59\xa7\x69\x89\x8d\x48\xfc\x45\xa4\x87\xa5\xb4\xce\x7f\xa7\x23\x88\x99\x03\xb6\x76\xc7\x0e\x64\xac\x16\xb2\xec\x2d\x78\xef\xfd\x02\xf3\xb0\x4f\xb3\x7b\x60\x24\x15\xae\xd8\x59\x81\xa7\x58\x75\x1f\xdf\x7d\xba\x84\x56\x92\x60\xa9\x60\x94\x6e\xeb\x91\x5e\x5a\xfb\xb0\x36\x85\x2c\x48\x87\x73\x0c\xa5\x9e\x26\xc9\xbc\x51\x42\x5a\xff\x11\x90\x06\x8c\x5b\xd7\xc2\xb2\x1b\xfc\xe2\xbc\x5f\x5a\x35\x24\x7b\xe1\x61\x1b\xd6\x04\xae\xc9\xd1\x52\x3e\xdc\xf0\x5e\xc2\x05\xd6\x54\x5d\xa0\xa1\xdf\xd8\x56\x6c\x15\x93\xb0\x11\x1e\x65\xad\x7e\x32\x1a\x6e\x0e\xea\xed\x2d\xb4\x40\x3e\x61\x5a\x5e\x3e\x08\xb1\x9c\x8c\xd0\x1c\x04\x16\x2d\x71\x20\x0d\x31\xad\x1d\xe3\xe1\xee\xe5\x73\x7c\x76\x38\x3b\x60\xfc\xa3\xdf\x14\x9c\xa8\x10\x54\xe5\x60\x37\x68\xe1\x56\x54\x15\x1b\xc9\x90\xf5\xf1\xa7\x1d\xc1\x7a\xe7\x25\xf3\x64\x0f\x35\xd1\x8e\x16\xa6\x8f\x96\x82\x52\xd6\x4a\x55\x84\x72\xb0\xba\xc5\x4a\xe4\x0f\x48\xf9\x99\xf7\x40\xed\x8c\x1d\x0a\x15\xd1\xd0\x13\x09\xa0\x13\x85\xf0\x57\x18\x91\x31\x22\x03\x1f\x6a\x23\xe2\x4b\xe4\x65\xd7\x66\xc3\x1c\x0a\x9c\x04\x01\x1e\xe5\x08\x16\xad\x33\xf7\xb9\x82\xdf\x70\xe0\x0c\x6a\xcd\x29\xf8\xeb\xbc\x21\x53\x32\x17\xb6\x9f\x62\x27\xf8\x1f\xa1\xcc\xe1\xe9\x0e\x32\x42\xe4\x3b\xad\x7d\xe8\xb7\x92\xf1\x64\x3f\x7b\x4d\x2b\x19\xe0\x1d\x66\x9b\x8e\x34\x6c\x90\xbd\xd0\x49\xf1\x8b\x23\xaf\x3e\x06\x77\xd0\x54\x54\x94\xd9\xa0\x89\xa8\x1c\x4e\x2c\x3e\x66\x44\x21\x32\x40\xfe\xcb\xb6\xcc\x3b\x86\x23\x1c\x3f\x59\x94\x39\xea\xbc\xc7\xd5\x47\x3d\x08\x99\x55\x2e\x1f\x89\x16\x36\xee\xc9\xdb\x2d\x8a\x0a\xd7\x15\x9d\xac\x0e\x78\x70\xdc\x14\xae\xaa\x76\x50\x38\x99\x31\x39\x1c\xf3\xb9\x04\x4e\x3e\x68\x55\x6a\x32\x5c\x52\x8c\xd0\x58\x13\x43\xb5\xaf\x1a\x29\x67\x9f\x8e\xe0\x38\x4e\xeb\x3b\x2a\x35\xe6\x94\x0f\x09\x15\x28\x2a\xca\x39\x34\x34\xb1\x66\x95\x86\x1a\x85\xb4\x28\x24\x30\x2c\x1f\x60\xca\x98\x76\x2e\x0f\x34\x4c\x87\xd6\xe1\xa4\x21\xbd\x89\x2f\x35\x27\xde\xef\xb1\x32\x74\xc6\x4c\xfe\x2a\x6f\xa4\xba\x95\xc7\x16\x16\x96\xea\x11\x77\x1b\x38\xdc\xc5\x9e\x05\xe3\x36\x0a\xc9\x92\x5a\x14\x95\xf1\xc5\x0e\x33\x3d\xb4\x70\xf4\xb9\x11\xba\xd0\xf7\x43\xe1\xeb\x22\xf8\x78\x8f\x03\x4e\x87\x4b\x18\x15\x1a\x7b\xa9\x51\x1a\xd1\x56\xf3\xe3\xfb\x1e\x13\x42\x53\x14\xdb\xfa\x8e\x57\xc0\xf2\x84\xbf\x63\xe7\x9f\xfb\xdd\x94\x87\xf4\xcb\x1a\x89\x66\xb2\x0a\x50\x2a\xbb\x21\x3d\x76\xbd\x30\x2e\x59\x13\xb1\xcc\x5a\x13\xdc\x6e\x48\x7a\x16\x4e\xe6\xa4\xab\x9d\xf7\xbc\xce\x04\x1b\x94\x25\xe5\x29\xc0\xfb\x22\xa4\x02\x61\x80\x33\xb6\x37\xf1\x19\x1f\x94\xe0\x4c\x5b\x59\x78\x79\xf7\x14\x59\xdd\x21\x89\x44\x32\x3e\xaf\x64\x19\x35\x96\x83\x67\x4a\xc4\x42\xe9\x1a\xed\x0a\xd8\xe5\x13\xa6\x38\xb1\x6f\x22\x0f\x77\xa3\x26\x63\xb0\xfc\x6a\x1b\x45\x32\x21\x29\x6e\x5c\x8d\x92\x03\x2a\xe7\x2b\x74\x6b\x32\x17\x99\xcf\x83\x7b\x67\xc5\xb5\x72\x01\x14\x3b\x93\x3d\x60\x15\x2e\xae\xd6\x0c\x73\x40\x75\x63\x77\xf1\x6e\x53\x87\x6a\xbc\xfb\x81\x64\xc9\xaf\xa9\x6f\x5e\xfe\xe9\xd5\xb7\x4f\x55\x53\x9b\x4e\xfe\x4c\x92\x9f\x53\x47\x6f\x82\x2f\xd7\xd8\x31\xc5\x5e\x65\xe9\x55\x92\xb6\xd5\x52\x5a\x76\x7b\xbc\x7f\x1d\x7a\xfb\x2d\x1a\x9f\xdf\xd7\x68\x28\x07\xd7\xdc\xa7\xc2\xef\x95\x06\x21\x8d\x45\x99\xd1\x19\x88\x62\x9c\x89\x30\x2d\x60\x54\x3b\x38\x7f\x79\x06\xeb\x68\xa5\x34\xc4\x50\xda\xe5\xb6\xab\xbb\xeb\x74\xe4\x2a\xc2\xc0\xeb\xb3\x81\x9c\x8c\x86\xce\x23\x12\x7b\xed\xa4\x88\xb7\xc2\x6e\x18\xa0\x3d\x7c\xc5\x87\xcc\x68\xca\x6c\xef\xf1\x50\x8c\x08\x69\x5f\xfd\x71\xca\x3f\x84\x14\xb5\xab\x57\xf0\xe2\x5e\xcf\xe0\x17\x54\x49\x7a\x74\x8f\x26\x34\x5f\xef\x0e\x81\x4a\x07\xe7\xc8\x40\x5b\x6a\xac\x6b\xb4\x22\x03\x91\x73\xd1\x5d\x08\xd2\xfd\x30\x0a\xa9\xcc\x1f\x6c\xdf\xb8\x7b\x75\xff\xc1\x44\x78\x7c\x44\x60\x7d\xd0\x2a\x77\x19\x3f\x5d\x54\xd1\xd5\x08\xc3\x7c\xcf\x91\x17\x4a\x2c\xa0\x3b\xb6\xce\xfe\x81\xe8\x8b\x8e\x9a\x50\x0a\x59\x9a\x28\x0a\xa7\x79\xc6\xb5\xb3\x49\xae\x7c\xe8\x76\x43\x8c\xc4\x6d\x41\xea\x69\x69\x7f\x0b\x23\x72\xe2\xcc\x8b\x50\x3a\xd4\x28\x2d\x51\xce\x68\x79\x1f\x3c\x44\x1a\x3d\xe4\xc6\xee\x65\xf4\x00\x52\x44\x78\x09\x58\xcc\x57\x8d\x6f\x2e\x8f\x32\x8f\x80\x97\xf3\x17\x2f\xef\x71\xb2\xfd\xae\x89\x2d\x0d\x5a\x7e\xa3\xaf\xe0\x9f\x57\x6f\x93\xbf\x63\xf2\xeb\xf5\xb3\xf8\xc7\x8b\xe4\xf5\xcf\x67\xab\xeb\xe7\xbd\xcf\xeb\xd3\x37\xbf\x7f\x2a\x90\x8d\xd5\xd2\xdd\x18\xab\xaa\xdb\x0a\xa2\xf5\x86\xb3\xd1\x9a\x66\xb2\xa0\x09\x83\xa4\xab\xa7\x98\x26\x70\xc2\xa4\x4e\xa6\x97\x3d\x8f\xe9\xf5\xc8\xfb\xa9\x2a\xf1\x1b\x1e\xa3\x10\x5f\x5f\xab\xa2\x0f\x69\xbd\x97\x37\x78\x68\x85\x42\xa9\x94\xee\xb0\x6e\x2a\x4a\x33\x55\x2f\x27\x5f\xe6\xed\xe8\xa7\xa8\xf3\x57\x0f\xfa\xc7\xb3\xab\xe0\x05\xd7\xcf\xae\x92\xf8\xd7\xf3\x76\xea\xf4\xcd\xb3\x7f\xa4\xf7\xae\x9f\x3e\x5f\x9e\xbe\x79\xd6\xf3\xad\xeb\xab\xa4\x73\xac\xf4\xfa\xf9\xe9\x9b\xde\xda\xe9\x13\xdd\x6c\xfc\xc5\x17\x46\x32\x52\xcf\x8d\x6e\x8b\x65\xc3\xe8\x5a\x00\xbd\xd1\xa5\xe0\xb5\xa3\x4b\x2c\xf5\xc8\xc2\xc4\xab\xb3\xbf\x88\x5a\xe3\xee\x68\xed\x2e\xb9\x71\x6b\xd2\x92\x2c\x99\xa4\x12\xc6\x26\x35\x36\xc9\x0d\xed\x46\xe2\x6b\x82\xfb\x31\x89\xc0\xb0\xc6\xe6\xe1\x97\xf1\xb1\x9a\x13\x8f\xde\x8b\xc9\x53\x21\x4f\xaf\x7c\x1f\x20\x36\xc5\x95\xe6\xf2\xaf\x37\xe3\xd6\xfb\x06\x5c\x4b\x38\x82\x06\xfc\xfb\xbf\xfd\x56\xed\xcb\xb9\x55\x3b\xb7\x6a\xe7\x56\x6d\x7f\xcc\xad\xda\x51\xd3\xfe\x3f\x5a\xb5\xc3\x7f\xef\x4d\x32\xbf\xd8\x6f\xf4\xce\x24\x21\x66\xe7\x58\xea\x1d\x32\x4f\xe1\x5d\x2e\x6c\x7f\xe6\x67\xaf\xb7\xb4\x54\x63\x99\x43\x81\xa6\x5a\x6d\x69\x19\xcc\x7d\xb4\xe5\xfe\x66\xc9\x54\xb7\xf9\xe8\x0a\x5f\xdc\x71\x9e\x2a\x35\x62\x1f\x7a\xba\xeb\x0c\x0f\x74\x9e\x61\xba\xfb\x7c\x24\xf5\x13\x3a\xd0\x13\x72\xfb\x8b\x3e\xaa\x0b\xfd\xb0\xfc\xd3\xb5\xc9\x58\x47\x1a\xee\xab\x0f\xa6\x1a\xdb\x9d\x6b\xce\xdd\xed\xb9\xbb\x3d\x77\xb7\xbb\x31\x77\xb7\x1f\x41\x71\xee\x6e\xcf\xdd\xed\xb9\xbb\x3d\x77\xb7\xe7\xee\xf6\xdc\xdd\xee\xc6\xdc\xdd\x9e\xbb\xdb\x23\x63\xee\x6e\xcf\xdd\x6d\x98\xbb\xdb\x0f\x74\xb7\x0b\x0e\xb1\xc7\xb4\xb7\x3b\x00\x09\x55\x2a\xe5\x3f\x0d\x7f\x29\x7d\x12\x42\xb5\xfd\x09\xb4\xff\xec\xbd\xa5\xdb\x5f\xad\x33\x6f\xca\xf7\xbf\xd1\x0e\xd3\xff\x0b\x00\x00\xff\xff\x09\x2a\x24\xd7\xd0\x2f\x00\x00") + +func manifestsWebhookOperatorsCoreosIo_webhooktestsYamlBytes() ([]byte, error) { + return bindataRead( + _manifestsWebhookOperatorsCoreosIo_webhooktestsYaml, + "manifests/webhook.operators.coreos.io_webhooktests.yaml", + ) +} + +func manifestsWebhookOperatorsCoreosIo_webhooktestsYaml() (*asset, error) { + bytes, err := manifestsWebhookOperatorsCoreosIo_webhooktestsYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "manifests/webhook.operators.coreos.io_webhooktests.yaml", size: 12240, mode: os.FileMode(420), modTime: time.Unix(1760064210, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _metadataAnnotationsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x92\xcd\x6e\x84\x30\x0c\x84\xef\x3c\x85\xa5\x1e\xab\xf5\x0a\x69\x4f\xdc\xaa\x3e\x48\x65\x12\xc3\xa6\x40\x8c\x1c\xc3\x8a\xb7\xaf\xca\x5f\x7f\x2e\x4d\x6f\x98\xcc\x7c\x9a\xc4\x43\x31\x8a\x91\x05\x89\xa9\x2a\x00\x9e\xe0\x55\x94\xa1\x9e\xa2\xef\x19\xbe\x1d\x62\x01\x20\x23\x2b\x99\x68\xc2\xe3\xab\x51\x1a\xf8\x21\xda\x61\x10\xdc\x4c\x38\xb0\x0f\x64\xcb\xc8\x38\x97\x15\x28\xb7\x21\x99\x2e\xcf\x73\x99\x4f\xa0\x18\x1a\x4e\x96\x56\xc2\x39\x5d\xff\x11\xc1\xc8\x93\xd1\xe6\xdf\x87\x7c\xfb\x48\xae\xa3\x76\xcb\xff\xe0\xfa\x2e\xd2\x5d\x0e\x7d\x36\xc4\xdd\x29\x46\xee\xb7\x3b\x50\x3f\xde\xe9\x6f\xeb\xc0\xa6\xc1\x25\xac\xa7\xd0\x7b\xd6\xea\xd4\x5f\x92\xef\x2e\x73\x89\xb7\x12\x33\x9e\xf1\xc0\xfc\xdc\xc4\xfe\x37\x6b\x11\x07\x61\x54\x79\x67\x67\x6f\x3d\x2d\x32\x59\x05\xad\x60\x37\xd5\xbc\xe7\xc3\x20\xd7\xf9\x56\xac\xb5\x79\xf9\xaa\x0a\x34\xa2\x60\x9c\x2c\xc4\x36\xa3\x36\x9f\xca\x5f\x51\x93\x13\x65\x47\xea\xb3\xc2\xae\x00\x27\xb1\x09\xed\xea\xb6\xb5\x2c\x27\xe3\x5a\x7c\x04\x00\x00\xff\xff\x1e\xcb\x90\x98\xe4\x02\x00\x00") + +func metadataAnnotationsYamlBytes() ([]byte, error) { + return bindataRead( + _metadataAnnotationsYaml, + "metadata/annotations.yaml", + ) +} + +func metadataAnnotationsYaml() (*asset, error) { + bytes, err := metadataAnnotationsYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "metadata/annotations.yaml", size: 740, mode: os.FileMode(420), modTime: time.Unix(1760064439, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _testsScorecardConfigYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x93\x3d\x6e\xc3\x30\x0c\x85\x77\x9f\x82\x17\x50\x82\xa2\x9b\xd6\x5e\xa0\x53\x77\x46\x66\x62\xc1\xb2\xa8\x92\x54\x82\xa0\xe8\xdd\x0b\x3b\x7f\x4d\x93\xa5\x05\xea\x6c\x36\xfd\xa8\xef\x7d\x06\x84\x25\xbe\x91\x68\xe4\xec\x41\x03\x0b\x05\x94\x76\xc1\x85\x04\x8d\x65\x2d\x38\xd0\x8e\xa5\x5f\x44\x5e\x6e\x9f\x30\x95\x0e\x9f\x9b\x3e\xe6\xd6\xc3\x0b\xe7\x75\xdc\x54\x41\x8b\x9c\x9b\x81\x0c\x5b\x34\xf4\x0d\x40\xc6\x81\x3c\x84\xe9\x7b\xa3\x86\x1b\x52\xdf\x38\x28\x28\x98\x12\x25\x0f\x26\x95\x1a\x00\x23\x35\x1d\x17\x1c\x50\x36\xd9\x17\x8e\xd9\xc6\xf7\x71\x72\x2e\xe3\xc6\xd8\x71\xb8\x42\x8d\xc1\x85\x8e\x42\xef\xb4\x50\x98\xc6\x71\xc0\x0d\x79\x78\xaf\xb8\x1f\x6b\x9e\xba\xbb\x73\xf9\xe5\xf5\x59\xbe\xe6\x3e\xf3\x2e\x4f\xcb\x09\x57\x94\xf4\x00\x05\xd0\x1a\x8d\xfc\x01\x73\x1c\x4d\x1b\x37\xe0\x4b\x29\x35\x96\x91\x7f\x3a\xa1\x50\x38\x3d\x03\x0c\x5c\xb3\xbd\xa2\x75\x1e\x3e\x3e\x7f\x23\xca\x69\x70\xab\x9a\xdb\x44\x6e\x8b\x29\xb6\x87\x9f\xfc\x3f\xb6\x9c\x86\x2b\xd7\xbb\xec\x39\x84\x83\xb4\xea\x3a\xdc\x3e\xc8\xf9\x1e\x7e\x5e\x6d\x21\xe5\x2a\x81\xf4\x21\xd6\x67\xfa\x1c\xd2\xd3\x25\x6a\x49\x83\xc4\x62\x2c\x73\x1a\xff\x44\xcf\xa2\x6b\x68\x55\x1f\x25\x7c\x03\xff\x93\xf2\xb7\xe8\x25\x76\x1d\xf9\x0a\x00\x00\xff\xff\xb8\xc2\xd4\xda\x4e\x06\x00\x00") + +func testsScorecardConfigYamlBytes() ([]byte, error) { + return bindataRead( + _testsScorecardConfigYaml, + "tests/scorecard/config.yaml", + ) +} + +func testsScorecardConfigYaml() (*asset, error) { + bytes, err := testsScorecardConfigYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "tests/scorecard/config.yaml", size: 1614, mode: os.FileMode(420), modTime: time.Unix(1760064391, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "Dockerfile": dockerfile, + "manifests/webhook-operator-controller-manager-metrics-service_v1_service.yaml": manifestsWebhookOperatorControllerManagerMetricsService_v1_serviceYaml, + "manifests/webhook-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml": manifestsWebhookOperatorMetricsReader_rbacAuthorizationK8sIo_v1_clusterroleYaml, + "manifests/webhook-operator-webhook-service_v1_service.yaml": manifestsWebhookOperatorWebhookService_v1_serviceYaml, + "manifests/webhook-operator-webhooktest-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml": manifestsWebhookOperatorWebhooktestAdminRole_rbacAuthorizationK8sIo_v1_clusterroleYaml, + "manifests/webhook-operator-webhooktest-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml": manifestsWebhookOperatorWebhooktestEditorRole_rbacAuthorizationK8sIo_v1_clusterroleYaml, + "manifests/webhook-operator-webhooktest-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml": manifestsWebhookOperatorWebhooktestViewerRole_rbacAuthorizationK8sIo_v1_clusterroleYaml, + "manifests/webhook-operator.clusterserviceversion.yaml": manifestsWebhookOperatorClusterserviceversionYaml, + "manifests/webhook.operators.coreos.io_webhooktests.yaml": manifestsWebhookOperatorsCoreosIo_webhooktestsYaml, + "metadata/annotations.yaml": metadataAnnotationsYaml, + "tests/scorecard/config.yaml": testsScorecardConfigYaml, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// +// data/ +// foo.txt +// img/ +// a.png +// b.png +// +// then AssetDir("data") would return []string{"foo.txt", "img"} +// AssetDir("data/img") would return []string{"a.png", "b.png"} +// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} + +var _bintree = &bintree{nil, map[string]*bintree{ + "Dockerfile": &bintree{dockerfile, map[string]*bintree{}}, + "manifests": &bintree{nil, map[string]*bintree{ + "webhook-operator-controller-manager-metrics-service_v1_service.yaml": &bintree{manifestsWebhookOperatorControllerManagerMetricsService_v1_serviceYaml, map[string]*bintree{}}, + "webhook-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml": &bintree{manifestsWebhookOperatorMetricsReader_rbacAuthorizationK8sIo_v1_clusterroleYaml, map[string]*bintree{}}, + "webhook-operator-webhook-service_v1_service.yaml": &bintree{manifestsWebhookOperatorWebhookService_v1_serviceYaml, map[string]*bintree{}}, + "webhook-operator-webhooktest-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml": &bintree{manifestsWebhookOperatorWebhooktestAdminRole_rbacAuthorizationK8sIo_v1_clusterroleYaml, map[string]*bintree{}}, + "webhook-operator-webhooktest-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml": &bintree{manifestsWebhookOperatorWebhooktestEditorRole_rbacAuthorizationK8sIo_v1_clusterroleYaml, map[string]*bintree{}}, + "webhook-operator-webhooktest-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml": &bintree{manifestsWebhookOperatorWebhooktestViewerRole_rbacAuthorizationK8sIo_v1_clusterroleYaml, map[string]*bintree{}}, + "webhook-operator.clusterserviceversion.yaml": &bintree{manifestsWebhookOperatorClusterserviceversionYaml, map[string]*bintree{}}, + "webhook.operators.coreos.io_webhooktests.yaml": &bintree{manifestsWebhookOperatorsCoreosIo_webhooktestsYaml, map[string]*bintree{}}, + }}, + "metadata": &bintree{nil, map[string]*bintree{ + "annotations.yaml": &bintree{metadataAnnotationsYaml, map[string]*bintree{}}, + }}, + "tests": &bintree{nil, map[string]*bintree{ + "scorecard": &bintree{nil, map[string]*bintree{ + "config.yaml": &bintree{testsScorecardConfigYaml, map[string]*bintree{}}, + }}, + }}, +}} + +// RestoreAsset restores an asset under the given directory +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) + if err != nil { + return err + } + return nil +} + +// RestoreAssets restores an asset under the given directory recursively +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + cannonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) +} diff --git a/openshift/tests-extension/pkg/bindata/webhook/index/index.go b/openshift/tests-extension/pkg/bindata/webhook/index/index.go new file mode 100644 index 000000000..9064419b2 --- /dev/null +++ b/openshift/tests-extension/pkg/bindata/webhook/index/index.go @@ -0,0 +1,271 @@ +// Code generated for package webhookindex by go-bindata DO NOT EDIT. (@generated) +// sources: +// testdata/webhook/index/Dockerfile +// testdata/webhook/index/configs/index.yaml +package webhookindex + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + clErr := gz.Close() + + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + if clErr != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +// Name return file name +func (fi bindataFileInfo) Name() string { + return fi.name +} + +// Size return file size +func (fi bindataFileInfo) Size() int64 { + return fi.size +} + +// Mode return file mode +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} + +// Mode return file modify time +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} + +// IsDir return file whether a directory +func (fi bindataFileInfo) IsDir() bool { + return fi.mode&os.ModeDir != 0 +} + +// Sys return file is sys mode +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _dockerfile = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x0b\xf2\xf7\x55\x28\x4e\x2e\x4a\x2c\x49\xce\xe0\x72\x74\x71\x51\x48\xce\xcf\x4b\xcb\x4c\x2f\x56\xd0\x87\x32\xb8\x7c\x1c\x9d\x5c\x7d\x14\xf2\x0b\x52\x8b\x12\x4b\xf2\x8b\x8a\xf5\x60\xac\xb4\xa2\xc4\xdc\xd4\xf2\xfc\xa2\x6c\xbd\xcc\x7c\xbd\xcc\xbc\x94\xd4\x0a\x3d\xa8\x16\xbd\x32\x43\x5b\xb8\x76\x40\x00\x00\x00\xff\xff\x47\x5b\xe3\x6f\x61\x00\x00\x00") + +func dockerfileBytes() ([]byte, error) { + return bindataRead( + _dockerfile, + "Dockerfile", + ) +} + +func dockerfile() (*asset, error) { + bytes, err := dockerfileBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "Dockerfile", size: 97, mode: os.FileMode(420), modTime: time.Unix(1760065068, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _configsIndexYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x53\x3d\x6f\x83\x30\x10\xdd\xf9\x15\x96\xe7\xe0\xd2\x4a\x59\xd8\xd2\x34\x5b\x1b\x55\x4a\xaa\x0e\x55\x07\x07\x2e\x60\x61\x6c\xcb\x36\x54\x11\xe2\xbf\x57\xe6\x2b\x05\x35\x24\x52\xa7\x66\xba\xdc\x7b\xef\xee\x3d\xa3\xab\x3c\x84\x10\xc2\x26\x4a\x21\xa7\x38\x44\x58\xf2\x9c\x28\x1a\x65\x34\x01\xbc\x68\x41\x41\x73\x70\xd0\x17\x1c\x52\x29\x33\x5f\x2a\xd0\xd4\x4a\xdd\xe3\x31\x1c\x69\xc1\xed\x3a\xa5\x42\x00\x77\x4c\xca\x55\x4a\xb1\x57\x7b\xbf\x8e\x8f\x3a\xe2\x64\x7c\x2b\xea\x9a\xbd\x85\x99\xb5\x20\xac\x66\x60\x70\x88\x3e\x9a\x86\xfb\x55\x43\x35\xeb\x9c\x94\x01\x09\xc8\x12\x0f\xec\xba\xa9\x3e\x2f\x39\x3e\x14\x22\xe6\x57\xdf\xa3\x9f\x7a\x7b\x04\x96\x77\x84\xa6\xf0\x35\x24\xcc\x58\x7d\x22\x52\x81\x30\x29\x3b\x5a\x7f\x02\x98\x32\x0a\x97\x41\x10\xdc\x55\x15\xda\xae\x5e\x36\xbb\xd7\xd5\x7a\x83\xea\xda\xfd\xdf\x6f\x76\x7b\xff\xf1\x6d\xfb\xf4\xec\x3a\x21\xa7\x16\x8c\x1d\xcc\x68\xb7\xdb\x5e\x79\x2f\x7b\x52\xd0\x67\x4e\xca\xac\x13\x0f\x70\x49\x79\xe1\xf0\xb1\xaa\x81\x12\x2d\x0b\xf5\x23\x2a\xe9\xa3\x1a\x12\x49\x0d\xd2\x10\x26\x27\xe3\x1a\x5d\xc6\x44\xec\x64\xef\xad\x6c\x7f\xb6\x3c\xde\x0c\xda\x30\x29\x1c\xb3\xbc\xc7\x23\xbc\x3e\x7f\xc4\xc5\xbf\xce\xf5\xf0\xb7\x5c\xe3\xa3\xbd\x25\x5b\xa7\xd8\xce\x9f\xf7\x25\xbf\x93\x0b\x9a\x58\x1e\xee\xc9\xfb\x0e\x00\x00\xff\xff\x10\x43\x2d\xf5\x62\x04\x00\x00") + +func configsIndexYamlBytes() ([]byte, error) { + return bindataRead( + _configsIndexYaml, + "configs/index.yaml", + ) +} + +func configsIndexYaml() (*asset, error) { + bytes, err := configsIndexYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "configs/index.yaml", size: 1122, mode: os.FileMode(420), modTime: time.Unix(1760066144, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "Dockerfile": dockerfile, + "configs/index.yaml": configsIndexYaml, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// +// data/ +// foo.txt +// img/ +// a.png +// b.png +// +// then AssetDir("data") would return []string{"foo.txt", "img"} +// AssetDir("data/img") would return []string{"a.png", "b.png"} +// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} + +var _bintree = &bintree{nil, map[string]*bintree{ + "Dockerfile": &bintree{dockerfile, map[string]*bintree{}}, + "configs": &bintree{nil, map[string]*bintree{ + "index.yaml": &bintree{configsIndexYaml, map[string]*bintree{}}, + }}, +}} + +// RestoreAsset restores an asset under the given directory +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) + if err != nil { + return err + } + return nil +} + +// RestoreAssets restores an asset under the given directory recursively +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + cannonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) +} diff --git a/openshift/tests-extension/pkg/helpers/image_registry.go b/openshift/tests-extension/pkg/helpers/image_registry.go new file mode 100644 index 000000000..85316baf1 --- /dev/null +++ b/openshift/tests-extension/pkg/helpers/image_registry.go @@ -0,0 +1,49 @@ +package helpers + +import ( + "context" + + //nolint:staticcheck // ST1001: dot-imports for readability + . "github.com/onsi/ginkgo/v2" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + + "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/env" + "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/extlogs" +) + +// RequireImageRegistry checks if the OpenShift image-registry is available in the cluster. +// If the image-registry is not available (either not installed or no pods running), it skips the test. +// This is necessary for tests that depend on the internal image registry service at +// image-registry.openshift-image-registry.svc:5000 +func RequireImageRegistry(ctx context.Context) { + if !env.Get().IsOpenShift { + extlogs.Warn("Skipping image-registry check: not OpenShift") + return + } + + clientset, err := kubernetes.NewForConfig(env.Get().RestCfg) + if err != nil { + extlogs.WarnContextf("Failed to create kubernetes client for image-registry check: %v", err) + Skip("Cannot verify image-registry availability: failed to create kubernetes client") + return + } + + // Check if there are any running image-registry pods + pods, err := clientset.CoreV1().Pods("openshift-image-registry").List(ctx, metav1.ListOptions{ + LabelSelector: "docker-registry=default", + }) + + if err != nil { + extlogs.WarnContextf("Failed to list image-registry pods: %v", err) + Skip("Cannot verify image-registry availability: failed to list pods") + return + } + + if len(pods.Items) == 0 { + Skip("Test requires image-registry to be available, but no image-registry pods found in openshift-image-registry namespace") + } + + extlogs.Infof("Image-registry is available with %d pod(s) running", len(pods.Items)) +} diff --git a/openshift/tests-extension/test/olmv1.go b/openshift/tests-extension/test/olmv1.go index c4c3e2623..d5e0ae818 100644 --- a/openshift/tests-extension/test/olmv1.go +++ b/openshift/tests-extension/test/olmv1.go @@ -107,7 +107,7 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLM][Skipped:Disconnected] OLMv1 } }) - It("should install an openshift catalog cluster extension", func(ctx SpecContext) { + It("should install an openshift catalog cluster extension", Label("original-name:[sig-olmv1][OCPFeatureGate:NewOLM][Skipped:Disconnected] OLMv1 operator installation should install an openshift catalog cluster extension"), func(ctx SpecContext) { if !env.Get().IsOpenShift { Skip("Requires OCP Catalogs: not OpenShift") } diff --git a/openshift/tests-extension/test/webhooks.go b/openshift/tests-extension/test/webhooks.go index 1cb1c06a1..6fa8211dc 100644 --- a/openshift/tests-extension/test/webhooks.go +++ b/openshift/tests-extension/test/webhooks.go @@ -1,5 +1,6 @@ package test +//nolint:gci // keep import order for readability import ( "context" "crypto/x509" @@ -24,8 +25,11 @@ import ( olmv1 "github.com/operator-framework/operator-controller/api/v1" + webhookbundle "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/bindata/webhook/bundle" + webhookindex "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/bindata/webhook/index" "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/env" "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/helpers" + "github.com/openshift/origin/test/extended/util/image" ) const ( @@ -35,13 +39,13 @@ const ( webhookServiceCert = "webhook-operator-controller-manager-service-cert" ) -var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks", +var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA] OLMv1 operator with webhooks", Ordered, Serial, func() { var ( k8sClient client.Client dynamicClient dynamic.Interface webhookOperatorInstallNamespace string - cleanup func(ctx context.Context) + unique string ) BeforeEach(func(ctx SpecContext) { @@ -55,25 +59,113 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServi By("requiring OLMv1 capability on OpenShift") helpers.RequireOLMv1CapabilityOnOpenshift() + By("requiring image-registry to be available") + helpers.RequireImageRegistry(ctx) + By("ensuring no ClusterExtension and CRD from a previous run") helpers.EnsureCleanupClusterExtension(ctx, webhookOperatorPackageName, webhookOperatorCRDName) - By(fmt.Sprintf("checking if the %s exists", webhookCatalogName)) - catalog := &olmv1.ClusterCatalog{} - err = k8sClient.Get(ctx, client.ObjectKey{Name: webhookCatalogName}, catalog) - if apierrors.IsNotFound(err) { - By(fmt.Sprintf("creating the webhook-operator catalog with name %s", webhookCatalogName)) - catalog = helpers.NewClusterCatalog(webhookCatalogName, "quay.io/operator-framework/webhook-operator-index:0.0.4") - err = k8sClient.Create(ctx, catalog) - Expect(err).ToNot(HaveOccurred()) - - By("waiting for the webhook-operator catalog to be serving") - helpers.ExpectCatalogToBeServing(ctx, webhookCatalogName) - } else { - By(fmt.Sprintf("webhook-operator catalog %s already exists, skipping creation", webhookCatalogName)) + unique = rand.String(8) + nsName := "webhook-olm-ns-" + unique + rbName := "webhook-olm-rb-" + unique + catalogName := webhookCatalogName + "-" + unique + bundleName := webhookOperatorPackageName + + replacements := map[string]string{ + "{{ TEST-BUNDLE }}": bundleName, + "{{ NAMESPACE }}": nsName, + "{{ TEST-CONTROLLER }}": image.LocationFor("quay.io/olmtest/webhook-operator:v0.0.5"), + } + + // Create namespace for building images + By("creating a new Namespace for builds") + nsCleanup := createNamespace(nsName) + DeferCleanup(nsCleanup) + + By(fmt.Sprintf("waiting for builder serviceaccount in %s", nsName)) + helpers.ExpectServiceAccountExists(ctx, "builder", nsName) + + By(fmt.Sprintf("waiting for deployer serviceaccount in %s", nsName)) + helpers.ExpectServiceAccountExists(ctx, "deployer", nsName) + + By("applying image-puller RoleBinding") + rbCleanup := createImagePullerRoleBinding(rbName, nsName) + DeferCleanup(rbCleanup) + + // Build bundle image + By("creating the operator bundle BuildConfig") + bcBundleCleanup := createBuildConfig(bundleName, nsName) + DeferCleanup(bcBundleCleanup) + + By("creating the operator bundle ImageStream") + isBundleCleanup := createImageStream(bundleName, nsName) + DeferCleanup(isBundleCleanup) + + By("creating the operator bundle tarball") + fileOperatorBundle, fileCleanupBundle := createTempTarBall(replacements, webhookbundle.AssetNames, webhookbundle.Asset) + DeferCleanup(fileCleanupBundle) + By(fmt.Sprintf("created operator bundle tarball %q", fileOperatorBundle)) + + By("starting the operator build via RAW URL") + opArgs := []string{ + "create", + "--raw", + fmt.Sprintf( + "/apis/build.openshift.io/v1/namespaces/%s/buildconfigs/%s/instantiatebinary?name=%s&namespace=%s", + nsName, bundleName, bundleName, nsName, + ), + "-f", + fileOperatorBundle, + } + buildOperatorBundle := startBuild(opArgs...) + + By(fmt.Sprintf("waiting for the build %q to finish", buildOperatorBundle.Name)) + waitForBuildToFinish(ctx, buildOperatorBundle.Name, nsName) + + // Build index image + By("creating the catalog BuildConfig") + bcIndexCleanup := createBuildConfig(catalogName, nsName) + DeferCleanup(bcIndexCleanup) + + By("creating the catalog ImageStream") + isIndexCleanup := createImageStream(catalogName, nsName) + DeferCleanup(isIndexCleanup) + + By("creating the catalog tarball") + fileCatalogIndex, fileCleanupIndex := createTempTarBall(replacements, webhookindex.AssetNames, webhookindex.Asset) + DeferCleanup(fileCleanupIndex) + By(fmt.Sprintf("created catalog tarball %q", fileCatalogIndex)) + + By("starting the catalog build via RAW URL") + indexArgs := []string{ + "create", + "--raw", + fmt.Sprintf( + "/apis/build.openshift.io/v1/namespaces/%s/buildconfigs/%s/instantiatebinary?name=%s&namespace=%s", + nsName, catalogName, catalogName, nsName, + ), + "-f", + fileCatalogIndex, } + buildCatalogIndex := startBuild(indexArgs...) + + By(fmt.Sprintf("waiting for the build %q to finish", buildCatalogIndex.Name)) + waitForBuildToFinish(ctx, buildCatalogIndex.Name, nsName) + + // Create ClusterCatalog + By("creating the ClusterCatalog") + catalogCleanup := createClusterCatalog(catalogName, nsName) + DeferCleanup(func(ctx context.Context) { + catalogCleanup() + }) + + By("waiting for the webhook-operator catalog to be serving") + helpers.ExpectCatalogToBeServing(ctx, catalogName) + + // Create ClusterExtension in a separate namespace + // setupWebhookOperator now registers its own DeferCleanup handlers internally webhookOperatorInstallNamespace = fmt.Sprintf("webhook-operator-%s", rand.String(5)) - cleanup = setupWebhookOperator(ctx, k8sClient, webhookOperatorInstallNamespace) + setupWebhookOperator(ctx, k8sClient, webhookOperatorInstallNamespace, catalogName) }) AfterEach(func(ctx SpecContext) { @@ -88,14 +180,11 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServi helpers.RunAndPrint(ctx, "get", "mutatingwebhookconfigurations.admissionregistration.k8s.io", "-oyaml") helpers.RunAndPrint(ctx, "get", "validatingwebhookconfigurations.admissionregistration.k8s.io", "-oyaml") } - - By("performing webhook operator cleanup") - if cleanup != nil { - cleanup(ctx) - } + // Note: cleanup is now handled by DeferCleanup in BeforeEach, which ensures + // cleanup runs even if BeforeEach or the test fails }) - It("should have a working validating webhook", func(ctx SpecContext) { + It("should have a working validating webhook", Label("original-name:[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working validating webhook"), func(ctx SpecContext) { By("creating a webhook test resource that will be rejected by the validating webhook") Eventually(func() error { name := fmt.Sprintf("validating-webhook-test-%s", rand.String(5)) @@ -121,7 +210,7 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServi }).WithTimeout(2 * time.Minute).WithPolling(5 * time.Second).Should(Succeed()) }) - It("should have a working mutating webhook", func(ctx SpecContext) { + It("should have a working mutating webhook [Serial]", Label("original-name:[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working mutating webhook"), func(ctx SpecContext) { By("creating a valid webhook") mutatingWebhookResourceName := "mutating-webhook-test" resource := newWebhookTest(mutatingWebhookResourceName, webhookOperatorInstallNamespace, true) @@ -143,7 +232,7 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServi })) }) - It("should have a working conversion webhook", func(ctx SpecContext) { + It("should have a working conversion webhook [Serial]", Label("original-name:[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should have a working conversion webhook"), func(ctx SpecContext) { By("creating a conversion webhook test resource") conversionWebhookResourceName := "conversion-webhook-test" resourceV1 := newWebhookTest(conversionWebhookResourceName, webhookOperatorInstallNamespace, true) @@ -167,7 +256,7 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServi })) }) - It("should be tolerant to tls secret deletion", func(ctx SpecContext) { + It("should be tolerant to tls secret deletion [Serial]", Label("original-name:[sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA][Skipped:Disconnected][Serial] OLMv1 operator with webhooks should be tolerant to tls secret deletion"), func(ctx SpecContext) { certificateSecretName := webhookServiceCert By("ensuring secret exists before deletion attempt") Eventually(func(g Gomega) { @@ -262,7 +351,7 @@ func newWebhookTest(name, namespace string, valid bool) *unstructured.Unstructur return obj } -func setupWebhookOperator(ctx SpecContext, k8sClient client.Client, webhookOperatorInstallNamespace string) func(ctx context.Context) { +func setupWebhookOperator(ctx SpecContext, k8sClient client.Client, webhookOperatorInstallNamespace, catalogName string) { By(fmt.Sprintf("installing the webhook operator in namespace %s", webhookOperatorInstallNamespace)) ns := &corev1.Namespace{ @@ -270,12 +359,27 @@ func setupWebhookOperator(ctx SpecContext, k8sClient client.Client, webhookOpera } err := k8sClient.Create(ctx, ns) Expect(err).ToNot(HaveOccurred()) + // Register cleanup immediately after creating the namespace + DeferCleanup(func(ctx context.Context) { + By(" NOW cleaning up ClusterExtension namespace (DeferCleanup executing) ") + By(fmt.Sprintf("cleanup: deleting namespace %s", ns.Name)) + _ = k8sClient.Delete(ctx, ns, client.PropagationPolicy(metav1.DeletePropagationForeground)) + + By(fmt.Sprintf("waiting for namespace %s to be fully deleted", webhookOperatorInstallNamespace)) + Eventually(func(g Gomega) { + tempNs := &corev1.Namespace{} + err := k8sClient.Get(ctx, client.ObjectKey{Name: webhookOperatorInstallNamespace}, tempNs) + g.Expect(client.IgnoreNotFound(err)).To(Succeed()) + g.Expect(apierrors.IsNotFound(err)).To(BeTrue(), "namespace still exists") + }).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).Should(Succeed()) + }) saName := fmt.Sprintf("%s-installer", webhookOperatorInstallNamespace) sa := helpers.NewServiceAccount(saName, webhookOperatorInstallNamespace) err = k8sClient.Create(ctx, sa) Expect(err).ToNot(HaveOccurred()) helpers.ExpectServiceAccountExists(ctx, saName, webhookOperatorInstallNamespace) + // ServiceAccount will be deleted with the namespace, no separate cleanup needed By("creating a ClusterRoleBinding to cluster-admin for the webhook operator") operatorClusterRoleBindingName := fmt.Sprintf("%s-operator-crb", webhookOperatorInstallNamespace) @@ -284,16 +388,36 @@ func setupWebhookOperator(ctx SpecContext, k8sClient client.Client, webhookOpera Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to create ClusterRoleBinding %s", operatorClusterRoleBindingName)) helpers.ExpectClusterRoleBindingExists(ctx, operatorClusterRoleBindingName) + // Register cleanup for ClusterRoleBinding (cluster-scoped resource) + DeferCleanup(func(ctx context.Context) { + By(" NOW cleaning up ClusterRoleBinding (DeferCleanup executing) ") + By(fmt.Sprintf("cleanup: deleting ClusterRoleBinding %s", operatorClusterRoleBinding.Name)) + _ = k8sClient.Delete(ctx, operatorClusterRoleBinding, client.PropagationPolicy(metav1.DeletePropagationBackground)) + }) ceName := webhookOperatorInstallNamespace - ce := helpers.NewClusterExtensionObject("webhook-operator", "0.0.4", ceName, saName, webhookOperatorInstallNamespace) + ce := helpers.NewClusterExtensionObject("webhook-operator", "0.0.5", ceName, saName, webhookOperatorInstallNamespace) ce.Spec.Source.Catalog.Selector = &metav1.LabelSelector{ MatchLabels: map[string]string{ - "olm.operatorframework.io/metadata.name": webhookCatalogName, + "olm.operatorframework.io/metadata.name": catalogName, }, } err = k8sClient.Create(ctx, ce) Expect(err).ToNot(HaveOccurred()) + // Register cleanup for ClusterExtension (cluster-scoped resource) + DeferCleanup(func(ctx context.Context) { + By(" NOW cleaning up ClusterExtension (DeferCleanup executing) ") + By(fmt.Sprintf("cleanup: deleting ClusterExtension %s", ce.Name)) + _ = k8sClient.Delete(ctx, ce, client.PropagationPolicy(metav1.DeletePropagationBackground)) + + By(fmt.Sprintf("waiting for ClusterExtension %s to be fully deleted", ce.Name)) + Eventually(func(g Gomega) { + tempCE := &olmv1.ClusterExtension{} + err := k8sClient.Get(ctx, client.ObjectKey{Name: ce.Name}, tempCE) + g.Expect(client.IgnoreNotFound(err)).To(Succeed()) + g.Expect(apierrors.IsNotFound(err)).To(BeTrue(), "ClusterExtension still exists") + }).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).Should(Succeed()) + }) By("waiting for the webhook operator to be installed") helpers.ExpectClusterExtensionToBeInstalled(ctx, ceName) @@ -324,24 +448,7 @@ func setupWebhookOperator(ctx SpecContext, k8sClient client.Client, webhookOpera g.Expect(secret.Data).ToNot(BeEmpty(), "expected webhook service certificate secret data to not be empty") }).WithTimeout(5*time.Minute).WithPolling(5*time.Second).Should(Succeed(), "webhook service certificate secret did not become available within timeout") - return func(ctx context.Context) { - By(fmt.Sprintf("cleanup: deleting ClusterExtension %s", ce.Name)) - _ = k8sClient.Delete(ctx, ce, client.PropagationPolicy(metav1.DeletePropagationBackground)) - By(fmt.Sprintf("cleanup: deleting ClusterRoleBinding %s", operatorClusterRoleBinding.Name)) - _ = k8sClient.Delete(ctx, operatorClusterRoleBinding, client.PropagationPolicy(metav1.DeletePropagationBackground)) - By(fmt.Sprintf("cleanup: deleting ServiceAccount %s in namespace %s", sa.Name, sa.Namespace)) - _ = k8sClient.Delete(ctx, sa, client.PropagationPolicy(metav1.DeletePropagationBackground)) - By(fmt.Sprintf("cleanup: deleting namespace %s", ns.Name)) - _ = k8sClient.Delete(ctx, ns, client.PropagationPolicy(metav1.DeletePropagationForeground)) - - By(fmt.Sprintf("waiting for namespace %s to be fully deleted", webhookOperatorInstallNamespace)) - Eventually(func(g Gomega) { - ns := &corev1.Namespace{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: webhookOperatorInstallNamespace}, ns) - g.Expect(client.IgnoreNotFound(err)).To(Succeed()) - g.Expect(apierrors.IsNotFound(err)).To(BeTrue(), "namespace still exists") - }).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).Should(Succeed()) - } + By("setupWebhookOperator completed - ClusterExtension is ready for test to use") } // printTLSCertInfo parses a PEM-encoded TLS certificate and prints useful debug info. diff --git a/openshift/tests-extension/testdata/webhook/bundle/Dockerfile b/openshift/tests-extension/testdata/webhook/bundle/Dockerfile new file mode 100644 index 000000000..3d4cd3454 --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/Dockerfile @@ -0,0 +1,20 @@ +FROM scratch + +# Core bundle labels. +LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 +LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ +LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ +LABEL operators.operatorframework.io.bundle.package.v1=registry +LABEL operators.operatorframework.io.bundle.channels.v1=alpha +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.34.1 +LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 +LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4 + +# Labels for testing. +LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 +LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ + +# Copy files to locations specified by labels. +COPY manifests /manifests/ +COPY metadata /metadata/ +COPY tests/scorecard /tests/scorecard/ diff --git a/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-controller-manager-metrics-service_v1_service.yaml b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-controller-manager-metrics-service_v1_service.yaml new file mode 100644 index 000000000..b069168bd --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-controller-manager-metrics-service_v1_service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: webhook-operator + control-plane: controller-manager + name: webhook-operator-controller-manager-metrics-service +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + app.kubernetes.io/name: webhook-operator + control-plane: controller-manager +status: + loadBalancer: {} diff --git a/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 000000000..20f88a159 --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,10 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: webhook-operator-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get diff --git a/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhook-service_v1_service.yaml b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhook-service_v1_service.yaml new file mode 100644 index 000000000..a7efc85ca --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhook-service_v1_service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: webhook-operator + name: webhook-operator-webhook-service +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + app.kubernetes.io/name: webhook-operator + control-plane: controller-manager +status: + loadBalancer: {} diff --git a/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhooktest-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhooktest-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 000000000..60769ecc8 --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhooktest-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,21 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: webhook-operator + name: webhook-operator-webhooktest-admin-role +rules: +- apiGroups: + - webhook.operators.coreos.io + resources: + - webhooktests + verbs: + - '*' +- apiGroups: + - webhook.operators.coreos.io + resources: + - webhooktests/status + verbs: + - get diff --git a/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhooktest-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhooktest-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 000000000..9212253f5 --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhooktest-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,27 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: webhook-operator + name: webhook-operator-webhooktest-editor-role +rules: +- apiGroups: + - webhook.operators.coreos.io + resources: + - webhooktests + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - webhook.operators.coreos.io + resources: + - webhooktests/status + verbs: + - get diff --git a/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhooktest-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhooktest-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 000000000..4274dbdf0 --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator-webhooktest-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,23 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: webhook-operator + name: webhook-operator-webhooktest-viewer-role +rules: +- apiGroups: + - webhook.operators.coreos.io + resources: + - webhooktests + verbs: + - get + - list + - watch +- apiGroups: + - webhook.operators.coreos.io + resources: + - webhooktests/status + verbs: + - get diff --git a/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator.clusterserviceversion.yaml b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator.clusterserviceversion.yaml new file mode 100644 index 000000000..97533f05b --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook-operator.clusterserviceversion.yaml @@ -0,0 +1,282 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "webhook.operators.coreos.io/v1", + "kind": "WebhookTest", + "metadata": { + "labels": { + "app.kubernetes.io/managed-by": "kustomize", + "app.kubernetes.io/name": "webhook-operator" + }, + "name": "webhooktest-sample" + }, + "spec": null + }, + { + "apiVersion": "webhook.operators.coreos.io/v2", + "kind": "WebhookTest", + "metadata": { + "labels": { + "app.kubernetes.io/managed-by": "kustomize", + "app.kubernetes.io/name": "webhook-operator" + }, + "name": "webhooktest-sample" + }, + "spec": null + } + ] + capabilities: Basic Install + operators.operatorframework.io/builder: operator-sdk-v1.41.1 + operators.operatorframework.io/project_layout: go.kubebuilder.io/v4 + name: webhook-operator.v0.0.5 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: WebhookTest is the Schema for the webhooktests API + displayName: Webhook Test + kind: WebhookTest + name: webhooktests.webhook.operators.coreos.io + version: v1 + - description: WebhookTest is the Schema for the webhooktests API + displayName: Webhook Test + kind: WebhookTest + name: webhooktests.webhook.operators.coreos.io + version: v2 + description: webhook-operator test fixture + displayName: webhook-operator + icon: + - base64data: "" + mediatype: "" + install: + spec: + clusterPermissions: + - rules: + - apiGroups: + - webhook.operators.coreos.io + resources: + - webhooktests + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - webhook.operators.coreos.io + resources: + - webhooktests/finalizers + verbs: + - update + - apiGroups: + - webhook.operators.coreos.io + resources: + - webhooktests/status + verbs: + - get + - patch + - update + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + serviceAccountName: webhook-operator-controller-manager + deployments: + - label: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: webhook-operator + control-plane: controller-manager + name: webhook-operator-controller-manager + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: webhook-operator + control-plane: controller-manager + strategy: {} + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + app.kubernetes.io/name: webhook-operator + control-plane: controller-manager + spec: + containers: + - args: + - --metrics-bind-address=:8443 + - --leader-elect + - --health-probe-bind-address=:8081 + - --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs + command: + - /manager + image: "{{ TEST-CONTROLLER }}" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: webhook-certs + readOnly: true + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: webhook-operator-controller-manager + terminationGracePeriodSeconds: 10 + volumes: + - name: webhook-certs + secret: + secretName: webhook-server-cert + permissions: + - rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + serviceAccountName: webhook-operator-controller-manager + strategy: deployment + installModes: + - supported: false + type: OwnNamespace + - supported: false + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces + keywords: + - test + - operator + - webhooks + links: + - name: Webhook Operator + url: https://webhook-operator.domain + maintainers: + - email: no-reply@operator-framework.io + name: no-reply + maturity: alpha + provider: + name: operator-framework + version: 0.0.5 + webhookdefinitions: + - admissionReviewVersions: + - v1 + containerPort: 443 + conversionCRDs: + - webhooktests.webhook.operators.coreos.io + deploymentName: webhook-operator-controller-manager + generateName: cwebhooktests.kb.io + sideEffects: None + targetPort: 9443 + type: ConversionWebhook + webhookPath: /convert + - admissionReviewVersions: + - v1 + containerPort: 443 + deploymentName: webhook-operator-controller-manager + failurePolicy: Fail + generateName: mwebhooktest-v1.kb.io + rules: + - apiGroups: + - webhook.operators.coreos.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - webhooktests + sideEffects: None + targetPort: 9443 + type: MutatingAdmissionWebhook + webhookPath: /mutate-webhook-operators-coreos-io-v1-webhooktest + - admissionReviewVersions: + - v1 + containerPort: 443 + deploymentName: webhook-operator-controller-manager + failurePolicy: Fail + generateName: vwebhooktest-v1.kb.io + rules: + - apiGroups: + - webhook.operators.coreos.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - webhooktests + sideEffects: None + targetPort: 9443 + type: ValidatingAdmissionWebhook + webhookPath: /validate-webhook-operators-coreos-io-v1-webhooktest diff --git a/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook.operators.coreos.io_webhooktests.yaml b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook.operators.coreos.io_webhooktests.yaml new file mode 100644 index 000000000..a5b692633 --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/manifests/webhook.operators.coreos.io_webhooktests.yaml @@ -0,0 +1,272 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: webhook-operator-system/webhook-operator-serving-cert + controller-gen.kubebuilder.io/version: v0.19.0 + creationTimestamp: null + name: webhooktests.webhook.operators.coreos.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: webhook-operator-webhook-service + namespace: webhook-operator-system + path: /convert + conversionReviewVersions: + - v1 + group: webhook.operators.coreos.io + names: + kind: WebhookTest + listKind: WebhookTestList + plural: webhooktests + singular: webhooktest + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: WebhookTest is the Schema for the webhooktests API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec defines the desired state of WebhookTest + properties: + mutate: + description: Mutate is a field that will be set to true by the mutating + webhook. + type: boolean + valid: + description: Valid must be set to true or the validation webhook will + reject the resource. + type: boolean + required: + - valid + type: object + status: + description: status defines the observed state of WebhookTest + properties: + conditions: + description: |- + conditions represent the current state of the WebhookTest resource. + Each condition has a unique type and reflects the status of a specific aspect of the resource. + + Standard condition types include: + - "Available": the resource is fully functional + - "Progressing": the resource is being created or updated + - "Degraded": the resource failed to reach or maintain its desired state + + The status of each condition is one of True, False, or Unknown. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - name: v2 + schema: + openAPIV3Schema: + description: WebhookTest is the Schema for the webhooktests API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec defines the desired state of WebhookTest + properties: + conversion: + description: Conversion is an example field of WebhookTest. Edit WebhookTest_types.go + to remove/update + properties: + mutate: + description: Mutate is a field that will be set to true by the + mutating webhook. + type: boolean + valid: + description: Valid must be set to true or the validation webhook + will reject the resource. + type: boolean + required: + - valid + type: object + required: + - conversion + type: object + status: + description: status defines the observed state of WebhookTest + properties: + conditions: + description: |- + conditions represent the current state of the WebhookTest resource. + Each condition has a unique type and reflects the status of a specific aspect of the resource. + + Standard condition types include: + - "Available": the resource is fully functional + - "Progressing": the resource is being created or updated + - "Degraded": the resource failed to reach or maintain its desired state + + The status of each condition is one of True, False, or Unknown. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/openshift/tests-extension/testdata/webhook/bundle/metadata/annotations.yaml b/openshift/tests-extension/testdata/webhook/bundle/metadata/annotations.yaml new file mode 100644 index 000000000..959444132 --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/metadata/annotations.yaml @@ -0,0 +1,14 @@ +annotations: + # Core bundle annotations. + operators.operatorframework.io.bundle.mediatype.v1: registry+v1 + operators.operatorframework.io.bundle.manifests.v1: manifests/ + operators.operatorframework.io.bundle.metadata.v1: metadata/ + operators.operatorframework.io.bundle.package.v1: webhook-operator + operators.operatorframework.io.bundle.channels.v1: alpha + operators.operatorframework.io.metrics.builder: operator-sdk-v1.41.1 + operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 + operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v4 + + # Annotations for testing. + operators.operatorframework.io.test.mediatype.v1: scorecard+v1 + operators.operatorframework.io.test.config.v1: tests/scorecard/ diff --git a/openshift/tests-extension/testdata/webhook/bundle/tests/scorecard/config.yaml b/openshift/tests-extension/testdata/webhook/bundle/tests/scorecard/config.yaml new file mode 100644 index 000000000..37b555ed2 --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/bundle/tests/scorecard/config.yaml @@ -0,0 +1,70 @@ +apiVersion: scorecard.operatorframework.io/v1alpha3 +kind: Configuration +metadata: + name: config +stages: +- parallel: true + tests: + - entrypoint: + - scorecard-test + - basic-check-spec + image: quay.io/operator-framework/scorecard-test:unknown + labels: + suite: basic + test: basic-check-spec-test + storage: + spec: + mountPath: {} + - entrypoint: + - scorecard-test + - olm-bundle-validation + image: quay.io/operator-framework/scorecard-test:unknown + labels: + suite: olm + test: olm-bundle-validation-test + storage: + spec: + mountPath: {} + - entrypoint: + - scorecard-test + - olm-crds-have-validation + image: quay.io/operator-framework/scorecard-test:unknown + labels: + suite: olm + test: olm-crds-have-validation-test + storage: + spec: + mountPath: {} + - entrypoint: + - scorecard-test + - olm-crds-have-resources + image: quay.io/operator-framework/scorecard-test:unknown + labels: + suite: olm + test: olm-crds-have-resources-test + storage: + spec: + mountPath: {} + - entrypoint: + - scorecard-test + - olm-spec-descriptors + image: quay.io/operator-framework/scorecard-test:unknown + labels: + suite: olm + test: olm-spec-descriptors-test + storage: + spec: + mountPath: {} + - entrypoint: + - scorecard-test + - olm-status-descriptors + image: quay.io/operator-framework/scorecard-test:unknown + labels: + suite: olm + test: olm-status-descriptors-test + storage: + spec: + mountPath: {} +storage: + spec: + mountPath: {} diff --git a/openshift/tests-extension/testdata/webhook/index/Dockerfile b/openshift/tests-extension/testdata/webhook/index/Dockerfile new file mode 100644 index 000000000..e865e9523 --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/index/Dockerfile @@ -0,0 +1,3 @@ +FROM scratch +ADD configs /configs +LABEL operators.operatorframework.io.index.configs.v1=/configs diff --git a/openshift/tests-extension/testdata/webhook/index/configs/index.yaml b/openshift/tests-extension/testdata/webhook/index/configs/index.yaml new file mode 100644 index 000000000..5df2a4227 --- /dev/null +++ b/openshift/tests-extension/testdata/webhook/index/configs/index.yaml @@ -0,0 +1,47 @@ +{ + "schema": "olm.package", + "name": "webhook-operator", + "defaultChannel": "alpha" +} +{ + "schema": "olm.channel", + "name": "alpha", + "package": "webhook-operator", + "entries": [ + { + "name": "webhook-operator.v0.0.5" + } + ] +} +{ + "schema": "olm.bundle", + "name": "webhook-operator.v0.0.5", + "package": "webhook-operator", + "image": "image-registry.openshift-image-registry.svc:5000/{{ NAMESPACE }}/{{ TEST-BUNDLE }}:latest", + "properties": [ + { + "type": "olm.gvk", + "value": { + "group": "webhook.operators.coreos.io", + "kind": "WebhookTest", + "version": "v1" + } + }, + { + "type": "olm.gvk", + "value": { + "group": "webhook.operators.coreos.io", + "kind": "WebhookTest", + "version": "v2" + } + }, + { + "type": "olm.package", + "value": { + "packageName": "webhook-operator", + "version": "0.0.5" + } + } + ] +} + diff --git a/openshift/tests-extension/vendor/github.com/openshift/origin/test/extended/util/image/image.go b/openshift/tests-extension/vendor/github.com/openshift/origin/test/extended/util/image/image.go index 2d7cca212..f71c99d47 100644 --- a/openshift/tests-extension/vendor/github.com/openshift/origin/test/extended/util/image/image.go +++ b/openshift/tests-extension/vendor/github.com/openshift/origin/test/extended/util/image/image.go @@ -59,6 +59,9 @@ var ( // used by external OIDC tests to simulate an external IdP "quay.io/keycloak/keycloak:25.0": -1, + + // image required for OLMv1 tests in https://github.com/openshift/operator-framework-operator-controller/tree/main/openshift/tests-extension + "quay.io/olmtest/webhook-operator:v0.0.5": -1, } ) diff --git a/openshift/tests-extension/vendor/github.com/openshift/origin/test/extended/util/image/zz_generated.txt b/openshift/tests-extension/vendor/github.com/openshift/origin/test/extended/util/image/zz_generated.txt index 1fda81fe7..77d9215ce 100644 --- a/openshift/tests-extension/vendor/github.com/openshift/origin/test/extended/util/image/zz_generated.txt +++ b/openshift/tests-extension/vendor/github.com/openshift/origin/test/extended/util/image/zz_generated.txt @@ -2,6 +2,7 @@ docker.io/library/registry:2.8.0-beta.1 quay.io/openshift/community-e2e-images:e2e-docker-io-library-registry-2-8-0-beta-1-8x_YFKSuz9Xw6lZD quay.io/keycloak/keycloak:25.0 quay.io/openshift/community-e2e-images:e2e-quay-io-keycloak-keycloak-25-0-rEIw9B2Zcc3L1M6k quay.io/kubevirt/fedora-with-test-tooling-container-disk:20241024_891122a6fc quay.io/openshift/community-e2e-images:e2e-quay-io-kubevirt-fedora-with-test-tooling-container-disk-20241024_891122a6fc-IycYTh-87XrXse4E +quay.io/olmtest/webhook-operator:v0.0.5 quay.io/openshift/community-e2e-images:e2e-quay-io-olmtest-webhook-operator-v0-0-5--2OhUsk-Xv-pLaTI quay.io/openshifttest/ldap:1.2 quay.io/openshift/community-e2e-images:e2e-quay-io-openshifttest-ldap-1-2-O3f5zPgtmWzEtasv quay.io/redhat-developer/nfs-server:1.1 quay.io/openshift/community-e2e-images:e2e-quay-io-redhat-developer-nfs-server-1-1-dlXGfzrk5aNo8EjC quay.io/redhat-developer/test-build-roots2i:1.2 quay.io/openshift/community-e2e-images:e2e-quay-io-redhat-developer-test-build-roots2i-1-2-gLJ7WcnS2TSllJ32 diff --git a/openshift/tests-extension/vendor/modules.txt b/openshift/tests-extension/vendor/modules.txt index 5c4fdca61..7a7ec66c1 100644 --- a/openshift/tests-extension/vendor/modules.txt +++ b/openshift/tests-extension/vendor/modules.txt @@ -387,7 +387,7 @@ github.com/openshift/client-go/user/applyconfigurations/user/v1 github.com/openshift/client-go/user/clientset/versioned github.com/openshift/client-go/user/clientset/versioned/scheme github.com/openshift/client-go/user/clientset/versioned/typed/user/v1 -# github.com/openshift/origin v1.5.0-alpha.3.0.20250927181537-6079513c8d63 +# github.com/openshift/origin v1.5.0-alpha.3.0.20251010041851-79ff1dbbe815 ## explicit; go 1.24.0 github.com/openshift/origin/test/extended/util/image # github.com/operator-framework/operator-controller v1.5.1