Created attachment 1678813 [details] Bundle for Nginx Operator Description of problem: In OpenShift 4.2 (OLM 0.11.0), installing an Operator bundle that contains "nullable: true" in CRD's openAPIV3Schema causes InstallPlan's CRD resolution/validation to completely remove any reference to it when building a plan (InstallPlan.status.plan) Version-Release number of selected component (if applicable): 4.2.27, olm 0.11.0 Steps to Reproduce: 1. Create a Subscription for latest version of Nginx Operator (nginx-ingress-operator Certified Operators) - set approval to manual. apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: nginx-ingress-operator namespace: default spec: channel: alpha installPlanApproval: Manual name: nginx-ingress-operator source: certified-operators sourceNamespace: openshift-marketplace startingCSV: nginx-ingress-operator.v0.0.3 2. Observe InstallPlan.status.resource for CRD - any reference to "nullable: true" key/values have been removed from the CRD. oc get installplan install-##### -o yaml | grep nullable Expected results: "nullable: true" should not be removed. Additional info: This issue does not appear in OCP 4.3 and 4.4. Attached copy of bundle. Verified that running `oc apply -f <crd>` within the same environment works fine and retains "nullable: true" within CRD.
Cluster version is 4.5.0-0.nightly-2020-05-21-032421 [root@preserve-olm-env data]# oc -n openshift-operator-lifecycle-manager exec catalog-operator-84df8896cf-9k9db -- olm --version OLM version: 0.15.0 git commit: e21670ca6955e353ae6cb5fe1cc020fba2442ab3 [root@preserve-olm-env data]# oc project default Now using project "default" on server "https://api.ci-ln-gci0hgb-f76d1.origin-ci-int-gce.dev.openshift.com:6443". [root@preserve-olm-env data]# oc create -f og.yaml operatorgroup.operators.coreos.com/test-og created [root@preserve-olm-env data]# oc create -f sub.yaml subscription.operators.coreos.com/nginx-ingress-operator created [root@preserve-olm-env data]# cat sub.yaml apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: nginx-ingress-operator namespace: default spec: channel: alpha installPlanApproval: Manual name: nginx-ingress-operator source: certified-operators sourceNamespace: openshift-marketplace startingCSV: nginx-ingress-operator.v0.0.3 [root@preserve-olm-env data]# oc get sub NAME PACKAGE SOURCE CHANNEL nginx-ingress-operator nginx-ingress-operator certified-operators alpha [root@preserve-olm-env data]# oc get ip NAME CSV APPROVAL APPROVED install-wbwzm nginx-ingress-operator.v0.0.3 Manual false [root@preserve-olm-env data]# oc get ip install-wbwzm -o yaml |grep nullable {"apiVersion":"apiextensions.k8s.io/v1beta1","kind":"CustomResourceDefinition","metadata":{"creationTimestamp":null,"name":"nginxingresscontrollers.k8s.nginx.org"},"spec":{"group":"k8s.nginx.org","names":{"kind":"NginxIngressController","listKind":"NginxIngressControllerList","plural":"nginxingresscontrollers","singular":"nginxingresscontroller"},"scope":"Namespaced","subresources":{"status":{}},"validation":{"openAPIV3Schema":{"description":"NginxIngressController is the Schema for the nginxingresscontrollers 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":"NginxIngressControllerSpec defines the desired state of NginxIngressController","properties":{"configMapData":{"additionalProperties":{"type":"string"},"description":"Initial values of the Ingress Controller ConfigMap. Check https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/configmap-resource/ for more information about possible values.","nullable":true,"type":"object"},"defaultSecret":{"description":"The TLS Secret for TLS termination of the default server. The format is namespace/name. If not specified, the operator will generate and deploy a TLS Secret with a self-signed certificate and key.","type":"string"},"enableCRDs":{"description":"Enables the use of NGINX Ingress Resource Definitions (VirtualServer and VirtualServerRoute).","type":"boolean"},"enableLeaderElection":{"description":"Enables Leader election to avoid multiple replicas of the controller reporting the status of Ingress resources – only one replica will report status.","type":"boolean"},"enableTLSPassthrough":{"description":"Enable TLS Passthrough on port 443. Requires enableCRDs set to true.","type":"boolean"},"globalConfiguration":{"description":"The GlobalConfiguration resource for global configuration of the Ingress Controller. Format is namespace/name. Requires enableCRDs set to true.","type":"string"},"healthStatus":{"description":"Adds a new location to the default server. The location responds with the 200 status code for any request. Useful for external health-checking of the Ingress controller.","nullable":true,"properties":{"enable":{"description":"Enable the HealthStatus.","type":"boolean"},"uri":{"description":"URI of the location. Default is `/nginx-health`.","type":"string"}},"required":["enable"],"type":"object"},"image":{"description":"The image of the Ingress Controller.","properties":{"pullPolicy":{"description":"The ImagePullPolicy of the image.","enum":["Never","Always","IfNotPresent"],"type":"string"},"repository":{"description":"The repository of the image.","type":"string"},"tag":{"description":"The tag (version) of the image.","type":"string"}},"required":["pullPolicy","repository","tag"],"type":"object"},"ingressClass":{"description":"A class of the Ingress controller. The Ingress controller only processes Ingress resources that belong to its class (in other words, have the annotation “kubernetes.io/ingress.class”). Additionally, the Ingress controller processes Ingress resources that do not have that annotation, which can be disabled by setting UseIngressClassOnly to true. Default is `nginx`.","type":"string"},"logLevel":{"description":"Log level for V logs. Format is 0 - 3","maximum":3,"minimum":0,"type":"integer"},"nginxDebug":{"description":"Enable debugging for NGINX. Uses the nginx-debug binary. Requires ‘error-log-level: debug’ in the ConfigMapData.","type":"boolean"},"nginxPlus":{"description":"Deploys the Ingress Controller for NGINX Plus. The default is false meaning the Ingress Controller will be deployed for NGINX OSS.","type":"boolean"},"nginxStatus":{"description":"NGINX stub_status, or the NGINX Plus API.","nullable":true,"properties":{"allowCidrs":{"description":"Whitelist IPv4 IP/CIDR blocks to allow access to NGINX stub_status or the NGINX Plus API. Separate multiple IP/CIDR by commas. (default “127.0.0.1”)","type":"string"},"enable":{"description":"Enable the NginxStatus.","type":"boolean"},"port":{"description":"Set the port where the NGINX stub_status or the NGINX Plus API is exposed. Default is 8080. Format is 1023 - 65535","maximum":65535,"minimum":1023,"nullable":true,"type":"integer"}},"required":["enable"],"type":"object"},"prometheus":{"description":"NGINX or NGINX Plus metrics in the Prometheus format.","nullable":true,"properties":{"enable":{"description":"Enable Prometheus metrics.","type":"boolean"},"port":{"description":"Sets the port where the Prometheus metrics are exposed. Default is 9113. Format is 1023 - 65535","maximum":65535,"minimum":1023,"nullable":true,"type":"integer"}},"required":["enable"],"type":"object"},"replicas":{"description":"The number of replicas of the Ingress Controller pod. The default is 1. Only applies if the type is set to deployment.","format":"int32","type":"integer"},"reportIngressStatus":{"description":"Update the address field in the status of Ingresses resources.","nullable":true,"properties":{"enable":{"description":"Enable the ReportIngressStatus.","type":"boolean"},"externalService":{"description":"Specifies the name of the service with the type LoadBalancer through which the Ingress controller pods are exposed externally. The external address of the service is used when reporting the status of Ingress resources. Note: Only if ServiceType is different than LoadBalancer.","type":"string"}},"required":["enable"],"type":"object"},"serviceType":{"description":"The type of the Service for the Ingress Controller. Valid Service types are: NodePort and LoadBalancer.","enum":["NodePort","LoadBalancer"],"type":"string"},"type":{"description":"The type of the Ingress Controller installation - deployment or daemonset.","enum":["deployment","daemonset"],"type":"string"},"useIngressClassOnly":{"description":"Ignore Ingress resources without the “kubernetes.io/ingress.class” annotation.","type":"boolean"},"watchNamespace":{"description":"Namespace to watch for Ingress resources. By default the Ingress controller watches all namespaces.","type":"string"},"wildcardTLS":{"description":"A Secret with a TLS certificate and key for TLS termination of every Ingress host for which TLS termination is enabled but the Secret is not specified. If the argument is not set, for such Ingress hosts NGINX will break any attempt to establish a TLS connection. If the argument is set, but the Ingress controller is not able to fetch the Secret from Kubernetes API, the Ingress Controller will fail to start. Format is namespace/name.","type":"string"}},"required":["enableCRDs","image","serviceType","type"],"type":"object"},"status":{"description":"NginxIngressControllerStatus defines the observed state of NginxIngressController","properties":{"deployed":{"description":"Deployed is true if the Operator has finished the deployment of the NginxIngressController.","type":"boolean"}},"required":["deployed"],"type":"object"}},"type":"object"}},"version":"v1alpha1","versions":[{"name":"v1alpha1","served":true,"storage":true}]},"status":{"acceptedNames":{"kind":"","plural":""},"conditions":null,"storedVersions":null}} The "nullable: true" exists, I couldn't reproduce this issue in 4.5, verify it.
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2020:2409