openshift-ci-robot: Hi @darkowlzz. Thanks for your PR.

I'm waiting for a [operator-framework](https://github.com/orgs/operator-framework/people) or [openshift](https://github.com/orgs/openshift/people) member to verify that this patch is reasonable to test. If it is, they should reply with `/ok-to-test` on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should [join the org](https://github.com/orgs/openshift/people) to skip this step.

Once the patch is verified, the new status will be reflected by the `ok-to-test` label.

I understand the commands that are listed [here](https://go.k8s.io/bot-commands?repo=operator-framework%2Foperator-courier).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>

diff --git a/operatorcourier/validate.py b/operatorcourier/validate.py
index 64b97bd..a140a27 100644
--- a/operatorcourier/validate.py
+++ b/operatorcourier/validate.py
@@ -176,7 +176,10 @@ class ValidateCmd():
             self._log_error("csv spec.installModes not defined")
             valid = False
 
-        if "install" not in spec:
+        if "install" in spec:
+            if self._csv_spec_install_validation(spec["install"]) is False:
+                valid = False
+        else:
             self._log_error("csv spec.install not defined")
             valid = False
 
@@ -256,6 +259,59 @@ class ValidateCmd():
                                         valid = False
         return valid
 
+    def _csv_spec_install_validation(self, install):
+        valid = True
+
+        wantStrategyList = ["deployment"]
+
+        # strategy check (required)
+        if "strategy" in install:
+            if install["strategy"] not in wantStrategyList:
+                self._log_error(
+                    "csv spec.install.strategy must be one of %s" % wantStrategyList)
+                valid = False
+        else:
+            self._log_error("csv spec.install.strategy not defined")
+            valid = False
+
+        # spec check (required)
+        if "spec" in install:
+            # deployments check (required)
+            if "deployments" in install["spec"]:
+                deployments = install["spec"]["deployments"]
+                if not isinstance(deployments, (list,)):
+                    self._log_error(
+                        "csv spec.install.spec.deployments should be a list")
+                    valid = False
+            else:
+                self._log_error("csv spec.install.spec.deployments not defined")
+
+            # permissions check (optional)
+            try:
+                permissions = install["spec"]["permissions"]
+                if not isinstance(permissions, (list,)):
+                    self._log_error("csv spec.install.spec.permissions should be a list")
+                    valid = False
+            except KeyError:
+                pass
+
+            # clusterPermissions check (optional)
+            try:
+                clusterPermissions = install["spec"]["clusterPermissions"]
+                if not isinstance(clusterPermissions, (list,)):
+                    self._log_error(
+                        "csv spec.install.spec.clusterPermissions should be a list"
+                    )
+                    valid = False
+            except KeyError:
+                pass
+
+        else:
+            self._log_error("csv spec.install.spec not defined")
+            valid = False
+
+        return valid
+
     def _csv_metadata_validation(self, metadata):
         valid = True
 

incorrect yaml for deployments not caught by linter
in the file below

```
spec:
  install:
    spec:
      deployments:
        name: robin-operator
        ....
        ....
        ....
```
should be
```
spec:
  install:
    spec:
      deployments:
        - name: robin-operator
          ....
          ....
          ....
```
 but it was not caught by operator-courier linting


```
apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
  name: robin-operator.v5.1.0
  namespace: default
  annotations:
      capabilities: Full Lifecycle
      categories: "Database,BigData,Storage"
      certified: "true"
      createdAt: 2019-04-08T01:00:00Z
      containerImage: registry.connect.redhat.com/robinsys/robin-operator:5.1.0-
      description: Robin Storage operator enables advanced data management capacilities to Kubernetes apps like snapshot,clone,rollback,backup,restore,import,etc.
      support: https://robin.io/support/
      alm-examples: >-
          [{ "apiVersion": "robin.io/v1alpha1", "kind": "RobinCluster", "metadata": { "name": "robin", "namespace": "default" }, "spec": { "host_type": "physical", "image_robin": "registry.connect.redhat.com/robinsys/robin-storage:5.1.0", "k8s_provider": "openshift", "node_selector": "node-role.kubernetes.io/compute=true" } } ]
spec:
  displayName: Robin Storage
  keywords: 
  - storage
  - big data 
  - csi
  - databases
  - postgresql
  - cloudera
  provider:
    name: Robin.io
  maturity: stable
  version: 5.1.0
  icon:
  - base64data: >-
      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
    mediatype: image/png
  links:
  - name: Robin
    url: 'https://robin.io'
  - name: User Guide
    url: 'https://get.robin.io/openshift/robin_ug'
  installModes:
  - type: OwnNamespace
    supported: true
  - type: SingleNamespace
    supported: false
  - type: MultiNamespace
    supported: false
  - type: AllNamespaces
    supported: false
  install:
    spec:
      deployments:
        name: robin-operator
        namespace: default
        spec:
          replicas: 1
          selector:
            matchLabels:
              name: robin-operator
          template:
            metadata:
              labels:
                name: robin-operator
                app.kubernetes.io/name: robin
            spec:
              serviceAccountName: robin-operator
              containers:
                - name: robin-operator
                  image: registry.connect.redhat.com/robinsys/robin-operator:5.1.0
                  command:
                  - robin-operator
                  env:
                    - name: WATCH_NAMESPACE
                      valueFrom:
                        fieldRef:
                          fieldPath: metadata.namespace
                    - name: POD_NAME
                      valueFrom:
                        fieldRef:
                          fieldPath: metadata.name
                    - name: OPERATOR_NAME
                      value: robin-operator
      clusterPermissions:
      - serviceAccountName: robin-operator
        rules:
        - apiGroups:
          - ""
          resources:
          - nodes
          verbs:
          - list
          - get
          - watch
        - apiGroups:
          - "rbac.authorization.k8s.io"
          resources:
          - clusterroles
          - clusterrolebindings
          verbs:
          - "*"
        - apiGroups:
          - "storage.k8s.io"
          resources:
          - storageclasses
          verbs:
          - "*"
      permissions:
      - serviceAccountName: robin-operator
        rules:
        - apiGroups:
          - ""
          resources:
          - pods
          - nodes
          - services
          - endpoints
          - persistentvolumeclaims
          - events
          - configmaps
          - secrets
          - serviceaccounts
          verbs:
          - "*"
        - apiGroups:
          - ""
          resources:
          - namespaces
          verbs:
          - get
        - apiGroups:
          - apps
          resources:
          - deployments
          - daemonsets
          - replicasets
          - statefulsets
          verbs:
          - "*"
        - apiGroups:
          - monitoring.coreos.com
          resources:
          - servicemonitors
          verbs:
          - get
          - create
        - apiGroups:
          - robin.io
          resources:
          - "*"
          verbs:
          - "*"
      strategy: deployment

  customresourcedefinitions:
    owned:
    - name: robinclusters.robin.io
      version: v1alpha1
      kind: RobinCluster
      group: robin.io
      displayName: Robin Cluster
      description: Robin storage deployment which enables storage and data management for all apps including helm charts.
      resources:
      - kind: RobinCluster
        name: ''
        version: v1alpha1
      - kind: ConfigMap
        name: ''
        version: v1
      - kind: Service
        name: ''
        version: v1
      - kind: ServiceAccount
        name: ''
        version: v1
      - kind: Node
        name: ''
        version: v1
      specDescriptors:
      - description: Type of the host
        displayName: Host Type
        path: host_type
        x-descriptors:
        - "urn:alm:descriptor:com.tectonic.ui:label"
      - description: Robin docker image
        displayName: Robin Image
        path: image_robin
        x-descriptors:
        - "urn:alm:descriptor:com.tectonic.ui:label"
      - description: Node selector to selet nodes on which Robin will deploy
        displayName: Node selector
        path: node_selector
        x-descriptors:
        - "urn:alm:descriptor:com.tectonic.ui:label"
      - description: Kubernetes provider eg. OpenShift
        displayName: Kubernetes Provider
        path: k8s_provider
        x-descriptors:
        - "urn:alm:descriptor:com.tectonic.ui:label"
      - description: Options
        displayName: Options
        path: options
        x-descriptors:
        - "urn:alm:descriptor:com.tectonic.ui:label"
      statusDescriptors:
      - description: IP of current Robin master
        displayName: Robin Master IP
        path: master_ip
        x-descriptors:
          - "urn:alm:descriptor:com.tectonic.ui:masterIP"
      - description: Command to Connect to Robin Master
        displayName: Connect Command
        path: connect_command
        x-descriptors:
          - "urn:alm:descriptor:com.tectonic.ui:connectCommand"
      - description: Command to Download Robin Master
        displayName: Get Robin Client
        path: get_robin_client
        x-descriptors:
          - "urn:alm:descriptor:com.tectonic.ui:getRobinClient"
      - description: The status of each of the Pods for the Robin cluster.
        displayName: Pod Status
        path: pod_status
        x-descriptors:
          - "urn:alm:descriptor:com.tectonic.ui:podStatuses"
      - description: The status of each of the Robin nodes in the cluster.
        displayName: Robin Node Status
        path: robin_node_status
        x-descriptors:
          - "urn:alm:descriptor:com.tectonic.ui:robinNodeStatuses"
      - description: Phase of the Robin cluster
        displayName: Phase
        path: phase
        x-descriptors:
          - "urn:alm:descriptor:com.tectonic.ui:phase"
  labels:
      app.kubernetes.io/name: robin
      operated-by: robin-operator
  selector:
    matchLabels:
      app.kubernetes.io/name: robina
  minKubeVersion: 1.11.0
  maintainers:
  - email: support@robin.io
    name: Robin
  description: >
    Robin Storage operator makes it very easy for users to snapshot, clone, rollback,
    backup, restore, import of helm charts on OpenShift.
     ## Supported Features
     
    * **Snapshot** -
    * **Clone** -
    * **Rollback** -
    * **Backup** -
    * **Restore** -
    * **Import** -



    ## About Robin Storage
    ROBIN Storage for OpenShift is a purpose-built container-native storage solution that brings advanced data management capabilities to OpenShift. 
    It provides automated provisioning, point-in-time snapshots, backup and recovery, application cloning, QoS guarantee, and 
    multi-cloud migration for stateful applications on OpenShift.
```

diff --git a/tests/test_files/bundles/verification/csvinstallspecnotlists.invalid.bundle.yaml b/tests/test_files/bundles/verification/csvinstallspecnotlists.invalid.bundle.yaml
new file mode 100644
index 0000000..be8bfb3
--- /dev/null
+++ b/tests/test_files/bundles/verification/csvinstallspecnotlists.invalid.bundle.yaml
@@ -0,0 +1,310 @@
+# CSV.spec.install.spec.{deployments,permissions,clusterPermissions} are not lists in this file
+data:
+  clusterServiceVersions: |
+    - apiVersion: operators.coreos.com/v1alpha1
+      kind: ClusterServiceVersion
+      metadata:
+        annotations:
+          alm-examples: '[{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"default"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["<etcd-cluster-endpoints>"],"storageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}}]'
+          categories: openshift required
+          certified: 'true'
+          containerImage: quay.io/openshift/origin-operator-marketplace:latest
+          createdAt: 2019/11/15
+          description: An operator to run the OpenShift marketplace
+          healthIndex: B
+          repository: https://github.com/operator-framework/operator-marketplace
+          support: Red Hat
+        name: marketplace-operator.v0.0.1
+        namespace: placeholder
+      spec:
+        customresourcedefinitions:
+          owned:
+          - description: Represents an OperatorSource.
+            displayName: Operator Source
+            kind: OperatorSource
+            name: operatorsources.marketplace.redhat.com
+            specDescriptors:
+            - description: The type of the operator source.
+              displayName: Type
+              path: type
+            - description: Points to the remote app registry server from where operator
+                manifests can be fetched.
+              displayName: Endpoint
+              path: endpoint
+            - description: 'The namespace in app registry.
+
+                Only operator manifests under this namespace will be visible.
+
+                Please note that this is not a k8s namespace.'
+              displayName: Registry Namespace
+              path: registryNamespace
+            statusDescriptors:
+            - description: Current status of the CatalogSourceConfig
+              displayName: Current Phase Name
+              path: currentPhase.phase.name
+            - description: Message associated with the current status
+              displayName: Current Phase Message
+              path: currentPhase.phase.message
+            version: v1alpha1
+          - description: Represents a CatalogSourceConfig object which is used to configure
+              a CatalogSource.
+            displayName: Catalog Source Config
+            kind: CatalogSourceConfig
+            name: catalogsourceconfigs.marketplace.redhat.com
+            specDescriptors:
+            - description: The namespace where the operators will be enabled.
+              displayName: Target Namespace
+              path: targetNamespace
+            - description: List of operator(s) which will be enabled in the target namespace
+              displayName: Packages
+              path: packages
+            statusDescriptors:
+            - description: Current status of the CatalogSourceConfig
+              displayName: Current Phase Name
+              path: currentPhase.phase.name
+            - description: Message associated with the current status
+              displayName: Current Phase Message
+              path: currentPhase.phase.message
+            version: v1alpha1
+        description: Marketplace is a gateway for users to consume off-cluster Operators
+          which will include Red Hat, ISV, optional OpenShift and community content.
+        displayName: marketplace-operator
+        install:
+          spec:
+            permissions:
+              rules:
+              - apiGroups:
+                - ""
+                resources:
+                - namespaces
+                verbs:
+                - get
+            clusterPermissions:
+              rules:
+              - apiGroups:
+                - marketplace.redhat.com
+                resources:
+                - '*'
+                verbs:
+                - '*'
+              - apiGroups:
+                - ''
+                resources:
+                - services
+                - configmaps
+                verbs:
+                - '*'
+              - apiGroups:
+                - operators.coreos.com
+                resources:
+                - catalogsources
+                verbs:
+                - '*'
+              serviceAccountName: marketplace-operator
+            deployments:
+              name: marketplace-operator
+              spec:
+                replicas: 1
+                selector:
+                  matchLabels:
+                    name: marketplace-operator
+                template:
+                  metadata:
+                    labels:
+                      name: marketplace-operator
+                    name: marketplace-operator
+                  spec:
+                    containers:
+                    - command:
+                      - marketplace-operator
+                      env:
+                      - name: WATCH_NAMESPACE
+                        valueFrom:
+                          fieldRef:
+                            fieldPath: metadata.namespace
+                      - name: OPERATOR_NAME
+                        value: marketplace-operator
+                      image: quay.io/openshift/origin-operator-marketplace:latest
+                      imagePullPolicy: Always
+                      livenessProbe:
+                        httpGet:
+                          path: /healthz
+                          port: 8080
+                      name: marketplace-operator
+                      ports:
+                      - containerPort: 60000
+                        name: metrics
+                      - containerPort: 8080
+                        name: healthz
+                      readinessProbe:
+                        httpGet:
+                          path: /healthz
+                          port: 8080
+                    serviceAccountName: marketplace-operator
+          strategy: deployment
+        installModes:
+        - supported: true
+          type: OwnNamespace
+        - supported: true
+          type: SingleNamespace
+        - supported: false
+          type: MultiNamespace
+        - supported: true
+          type: AllNamespaces
+        keywords:
+        - marketplace
+        - catalog
+        - olm
+        - admin
+        labels:
+          name: marketplace-operator
+        links:
+        - name: Markplace Operator Source Code
+          url: https://github.com/operator-framework/operator-marketplace
+        maintainers:
+        - email: aos-marketplace@redhat.com
+          name: AOS Marketplace Team
+        maturity: alpha
+        provider:
+          name: Red Hat
+        selector:
+          matchLabels:
+            name: marketplace-operator
+        version: 0.0.1
+  customResourceDefinitions: |
+    - apiVersion: apiextensions.k8s.io/v1beta1
+      kind: CustomResourceDefinition
+      metadata:
+        annotations:
+          description: Represents a CatalogSourceConfig.
+          displayName: Catalog Source Config
+        name: catalogsourceconfigs.marketplace.redhat.com
+      spec:
+        additionalPrinterColumns:
+        - JSONPath: .spec.targetNamespace
+          description: The namespace where the operators will be enabled
+          name: TargetNamespace
+          type: string
+        - JSONPath: .spec.packages
+          description: List of operator(s) which will be enabled in the target namespace
+          name: Packages
+          type: string
+        - JSONPath: .status.currentPhase.phase.name
+          description: Current status of the CatalogSourceConfig
+          name: Status
+          type: string
+        - JSONPath: .status.currentPhase.phase.message
+          description: Message associated with the current status
+          name: Message
+          type: string
+        - JSONPath: .metadata.creationTimestamp
+          name: Age
+          type: date
+        group: marketplace.redhat.com
+        names:
+          kind: CatalogSourceConfig
+          listKind: CatalogSourceConfigList
+          plural: catalogsourceconfigs
+          shortNames:
+          - csc
+          singular: catalogsourceconfig
+        scope: Namespaced
+        validation:
+          openAPIV3Schema:
+            properties:
+              spec:
+                description: Spec for a CatalogSourceConfig
+                properties:
+                  packages:
+                    description: Comma separated list of operator(s) without spaces
+                      which will be enabled in the target namespace
+                    type: string
+                  targetNamespace:
+                    description: The namespace where the operators will be enabled
+                    type: string
+                required:
+                - targetNamespace
+                - packages
+                type: object
+        version: v1alpha1
+    - apiVersion: apiextensions.k8s.io/v1beta1
+      kind: CustomResourceDefinition
+      metadata:
+        annotations:
+          description: Represents an OperatorSource.
+          displayName: Operator Source
+        name: operatorsources.marketplace.redhat.com
+      spec:
+        additionalPrinterColumns:
+        - JSONPath: .spec.type
+          description: The type of the OperatorSource
+          name: Type
+          type: string
+        - JSONPath: .spec.endpoint
+          description: The endpoint of the OperatorSource
+          name: Endpoint
+          type: string
+        - JSONPath: .spec.registryNamespace
+          description: App registry namespace
+          name: Registry
+          type: string
+        - JSONPath: .spec.displayName
+          description: Display (pretty) name to indicate the OperatorSource's name
+          name: DisplayName
+          type: string
+        - JSONPath: .spec.publisher
+          description: Publisher of the OperatorSource
+          name: Publisher
+          type: string
+        - JSONPath: .status.currentPhase.phase.name
+          description: Current status of the OperatorSource
+          name: Status
+          type: string
+        - JSONPath: .status.currentPhase.phase.message
+          description: Message associated with the current status
+          name: Message
+          type: string
+        - JSONPath: .metadata.creationTimestamp
+          name: Age
+          type: date
+        group: marketplace.redhat.com
+        names:
+          kind: OperatorSource
+          listKind: OperatorSourceList
+          plural: operatorsources
+          shortNames:
+          - opsrc
+          singular: operatorsource
+        scope: Namespaced
+        validation:
+          openAPIV3Schema:
+            properties:
+              spec:
+                description: Spec for an OperatorSource.
+                properties:
+                  endpoint:
+                    description: Points to the remote app registry server from where
+                      operator manifests can be fetched.
+                    type: string
+                  registryNamespace:
+                    description: 'The namespace in app registry.
+
+                      Only operator manifests under this namespace will be visible.
+
+                      Please note that this is not a k8s namespace.'
+                    type: string
+                  type:
+                    description: The type of the OperatorSource
+                    pattern: appregistry
+                    type: string
+                required:
+                - type
+                - endpoint
+                - registryNamespace
+                type: object
+        version: v1alpha1
+  packages: |
+    - channels:
+      - currentCSV: marketplace-operator.v0.0.1
+        name: alpha
+      packageName: marketplace
diff --git a/tests/test_files/bundles/verification/csvinstallstrategywrongvalue.invalid.bundle.yaml b/tests/test_files/bundles/verification/csvinstallstrategywrongvalue.invalid.bundle.yaml
new file mode 100644
index 0000000..1bdd81a
--- /dev/null
+++ b/tests/test_files/bundles/verification/csvinstallstrategywrongvalue.invalid.bundle.yaml
@@ -0,0 +1,310 @@
+# CSV.spec.install.strategy has unexpected value in this file
+data:
+  clusterServiceVersions: |
+    - apiVersion: operators.coreos.com/v1alpha1
+      kind: ClusterServiceVersion
+      metadata:
+        annotations:
+          alm-examples: '[{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"default"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["<etcd-cluster-endpoints>"],"storageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}}]'
+          categories: openshift required
+          certified: 'true'
+          containerImage: quay.io/openshift/origin-operator-marketplace:latest
+          createdAt: 2019/11/15
+          description: An operator to run the OpenShift marketplace
+          healthIndex: B
+          repository: https://github.com/operator-framework/operator-marketplace
+          support: Red Hat
+        name: marketplace-operator.v0.0.1
+        namespace: placeholder
+      spec:
+        customresourcedefinitions:
+          owned:
+          - description: Represents an OperatorSource.
+            displayName: Operator Source
+            kind: OperatorSource
+            name: operatorsources.marketplace.redhat.com
+            specDescriptors:
+            - description: The type of the operator source.
+              displayName: Type
+              path: type
+            - description: Points to the remote app registry server from where operator
+                manifests can be fetched.
+              displayName: Endpoint
+              path: endpoint
+            - description: 'The namespace in app registry.
+
+                Only operator manifests under this namespace will be visible.
+
+                Please note that this is not a k8s namespace.'
+              displayName: Registry Namespace
+              path: registryNamespace
+            statusDescriptors:
+            - description: Current status of the CatalogSourceConfig
+              displayName: Current Phase Name
+              path: currentPhase.phase.name
+            - description: Message associated with the current status
+              displayName: Current Phase Message
+              path: currentPhase.phase.message
+            version: v1alpha1
+          - description: Represents a CatalogSourceConfig object which is used to configure
+              a CatalogSource.
+            displayName: Catalog Source Config
+            kind: CatalogSourceConfig
+            name: catalogsourceconfigs.marketplace.redhat.com
+            specDescriptors:
+            - description: The namespace where the operators will be enabled.
+              displayName: Target Namespace
+              path: targetNamespace
+            - description: List of operator(s) which will be enabled in the target namespace
+              displayName: Packages
+              path: packages
+            statusDescriptors:
+            - description: Current status of the CatalogSourceConfig
+              displayName: Current Phase Name
+              path: currentPhase.phase.name
+            - description: Message associated with the current status
+              displayName: Current Phase Message
+              path: currentPhase.phase.message
+            version: v1alpha1
+        description: Marketplace is a gateway for users to consume off-cluster Operators
+          which will include Red Hat, ISV, optional OpenShift and community content.
+        displayName: marketplace-operator
+        install:
+          spec:
+            permissions:
+            - rules:
+              - apiGroups:
+                - ""
+                resources:
+                - namespaces
+                verbs:
+                - get
+            clusterPermissions:
+            - rules:
+              - apiGroups:
+                - marketplace.redhat.com
+                resources:
+                - '*'
+                verbs:
+                - '*'
+              - apiGroups:
+                - ''
+                resources:
+                - services
+                - configmaps
+                verbs:
+                - '*'
+              - apiGroups:
+                - operators.coreos.com
+                resources:
+                - catalogsources
+                verbs:
+                - '*'
+              serviceAccountName: marketplace-operator
+            deployments:
+            - name: marketplace-operator
+              spec:
+                replicas: 1
+                selector:
+                  matchLabels:
+                    name: marketplace-operator
+                template:
+                  metadata:
+                    labels:
+                      name: marketplace-operator
+                    name: marketplace-operator
+                  spec:
+                    containers:
+                    - command:
+                      - marketplace-operator
+                      env:
+                      - name: WATCH_NAMESPACE
+                        valueFrom:
+                          fieldRef:
+                            fieldPath: metadata.namespace
+                      - name: OPERATOR_NAME
+                        value: marketplace-operator
+                      image: quay.io/openshift/origin-operator-marketplace:latest
+                      imagePullPolicy: Always
+                      livenessProbe:
+                        httpGet:
+                          path: /healthz
+                          port: 8080
+                      name: marketplace-operator
+                      ports:
+                      - containerPort: 60000
+                        name: metrics
+                      - containerPort: 8080
+                        name: healthz
+                      readinessProbe:
+                        httpGet:
+                          path: /healthz
+                          port: 8080
+                    serviceAccountName: marketplace-operator
+          strategy: foodeployment
+        installModes:
+        - supported: true
+          type: OwnNamespace
+        - supported: true
+          type: SingleNamespace
+        - supported: false
+          type: MultiNamespace
+        - supported: true
+          type: AllNamespaces
+        keywords:
+        - marketplace
+        - catalog
+        - olm
+        - admin
+        labels:
+          name: marketplace-operator
+        links:
+        - name: Markplace Operator Source Code
+          url: https://github.com/operator-framework/operator-marketplace
+        maintainers:
+        - email: aos-marketplace@redhat.com
+          name: AOS Marketplace Team
+        maturity: alpha
+        provider:
+          name: Red Hat
+        selector:
+          matchLabels:
+            name: marketplace-operator
+        version: 0.0.1
+  customResourceDefinitions: |
+    - apiVersion: apiextensions.k8s.io/v1beta1
+      kind: CustomResourceDefinition
+      metadata:
+        annotations:
+          description: Represents a CatalogSourceConfig.
+          displayName: Catalog Source Config
+        name: catalogsourceconfigs.marketplace.redhat.com
+      spec:
+        additionalPrinterColumns:
+        - JSONPath: .spec.targetNamespace
+          description: The namespace where the operators will be enabled
+          name: TargetNamespace
+          type: string
+        - JSONPath: .spec.packages
+          description: List of operator(s) which will be enabled in the target namespace
+          name: Packages
+          type: string
+        - JSONPath: .status.currentPhase.phase.name
+          description: Current status of the CatalogSourceConfig
+          name: Status
+          type: string
+        - JSONPath: .status.currentPhase.phase.message
+          description: Message associated with the current status
+          name: Message
+          type: string
+        - JSONPath: .metadata.creationTimestamp
+          name: Age
+          type: date
+        group: marketplace.redhat.com
+        names:
+          kind: CatalogSourceConfig
+          listKind: CatalogSourceConfigList
+          plural: catalogsourceconfigs
+          shortNames:
+          - csc
+          singular: catalogsourceconfig
+        scope: Namespaced
+        validation:
+          openAPIV3Schema:
+            properties:
+              spec:
+                description: Spec for a CatalogSourceConfig
+                properties:
+                  packages:
+                    description: Comma separated list of operator(s) without spaces
+                      which will be enabled in the target namespace
+                    type: string
+                  targetNamespace:
+                    description: The namespace where the operators will be enabled
+                    type: string
+                required:
+                - targetNamespace
+                - packages
+                type: object
+        version: v1alpha1
+    - apiVersion: apiextensions.k8s.io/v1beta1
+      kind: CustomResourceDefinition
+      metadata:
+        annotations:
+          description: Represents an OperatorSource.
+          displayName: Operator Source
+        name: operatorsources.marketplace.redhat.com
+      spec:
+        additionalPrinterColumns:
+        - JSONPath: .spec.type
+          description: The type of the OperatorSource
+          name: Type
+          type: string
+        - JSONPath: .spec.endpoint
+          description: The endpoint of the OperatorSource
+          name: Endpoint
+          type: string
+        - JSONPath: .spec.registryNamespace
+          description: App registry namespace
+          name: Registry
+          type: string
+        - JSONPath: .spec.displayName
+          description: Display (pretty) name to indicate the OperatorSource's name
+          name: DisplayName
+          type: string
+        - JSONPath: .spec.publisher
+          description: Publisher of the OperatorSource
+          name: Publisher
+          type: string
+        - JSONPath: .status.currentPhase.phase.name
+          description: Current status of the OperatorSource
+          name: Status
+          type: string
+        - JSONPath: .status.currentPhase.phase.message
+          description: Message associated with the current status
+          name: Message
+          type: string
+        - JSONPath: .metadata.creationTimestamp
+          name: Age
+          type: date
+        group: marketplace.redhat.com
+        names:
+          kind: OperatorSource
+          listKind: OperatorSourceList
+          plural: operatorsources
+          shortNames:
+          - opsrc
+          singular: operatorsource
+        scope: Namespaced
+        validation:
+          openAPIV3Schema:
+            properties:
+              spec:
+                description: Spec for an OperatorSource.
+                properties:
+                  endpoint:
+                    description: Points to the remote app registry server from where
+                      operator manifests can be fetched.
+                    type: string
+                  registryNamespace:
+                    description: 'The namespace in app registry.
+
+                      Only operator manifests under this namespace will be visible.
+
+                      Please note that this is not a k8s namespace.'
+                    type: string
+                  type:
+                    description: The type of the OperatorSource
+                    pattern: appregistry
+                    type: string
+                required:
+                - type
+                - endpoint
+                - registryNamespace
+                type: object
+        version: v1alpha1
+  packages: |
+    - channels:
+      - currentCSV: marketplace-operator.v0.0.1
+        name: alpha
+      packageName: marketplace
diff --git a/tests/test_files/bundles/verification/csvmissinginstallattributes.invalid.bundle.yaml b/tests/test_files/bundles/verification/csvmissinginstallattributes.invalid.bundle.yaml
new file mode 100644
index 0000000..00007c8
--- /dev/null
+++ b/tests/test_files/bundles/verification/csvmissinginstallattributes.invalid.bundle.yaml
@@ -0,0 +1,239 @@
+# CSV.spec.install.{strategy,spec} are missing in this file
+data:
+  clusterServiceVersions: |
+    - apiVersion: operators.coreos.com/v1alpha1
+      kind: ClusterServiceVersion
+      metadata:
+        annotations:
+          alm-examples: '[{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"default"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["<etcd-cluster-endpoints>"],"storageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}}]'
+          categories: openshift required
+          certified: 'true'
+          containerImage: quay.io/openshift/origin-operator-marketplace:latest
+          createdAt: 2019/11/15
+          description: An operator to run the OpenShift marketplace
+          healthIndex: B
+          repository: https://github.com/operator-framework/operator-marketplace
+          support: Red Hat
+        name: marketplace-operator.v0.0.1
+        namespace: placeholder
+      spec:
+        customresourcedefinitions:
+          owned:
+          - description: Represents an OperatorSource.
+            displayName: Operator Source
+            kind: OperatorSource
+            name: operatorsources.marketplace.redhat.com
+            specDescriptors:
+            - description: The type of the operator source.
+              displayName: Type
+              path: type
+            - description: Points to the remote app registry server from where operator
+                manifests can be fetched.
+              displayName: Endpoint
+              path: endpoint
+            - description: 'The namespace in app registry.
+
+                Only operator manifests under this namespace will be visible.
+
+                Please note that this is not a k8s namespace.'
+              displayName: Registry Namespace
+              path: registryNamespace
+            statusDescriptors:
+            - description: Current status of the CatalogSourceConfig
+              displayName: Current Phase Name
+              path: currentPhase.phase.name
+            - description: Message associated with the current status
+              displayName: Current Phase Message
+              path: currentPhase.phase.message
+            version: v1alpha1
+          - description: Represents a CatalogSourceConfig object which is used to configure
+              a CatalogSource.
+            displayName: Catalog Source Config
+            kind: CatalogSourceConfig
+            name: catalogsourceconfigs.marketplace.redhat.com
+            specDescriptors:
+            - description: The namespace where the operators will be enabled.
+              displayName: Target Namespace
+              path: targetNamespace
+            - description: List of operator(s) which will be enabled in the target namespace
+              displayName: Packages
+              path: packages
+            statusDescriptors:
+            - description: Current status of the CatalogSourceConfig
+              displayName: Current Phase Name
+              path: currentPhase.phase.name
+            - description: Message associated with the current status
+              displayName: Current Phase Message
+              path: currentPhase.phase.message
+            version: v1alpha1
+        description: Marketplace is a gateway for users to consume off-cluster Operators
+          which will include Red Hat, ISV, optional OpenShift and community content.
+        displayName: marketplace-operator
+        install:
+          somefield: somevalue
+        installModes:
+        - supported: true
+          type: OwnNamespace
+        - supported: true
+          type: SingleNamespace
+        - supported: false
+          type: MultiNamespace
+        - supported: true
+          type: AllNamespaces
+        keywords:
+        - marketplace
+        - catalog
+        - olm
+        - admin
+        labels:
+          name: marketplace-operator
+        links:
+        - name: Markplace Operator Source Code
+          url: https://github.com/operator-framework/operator-marketplace
+        maintainers:
+        - email: aos-marketplace@redhat.com
+          name: AOS Marketplace Team
+        maturity: alpha
+        provider:
+          name: Red Hat
+        selector:
+          matchLabels:
+            name: marketplace-operator
+        version: 0.0.1
+  customResourceDefinitions: |
+    - apiVersion: apiextensions.k8s.io/v1beta1
+      kind: CustomResourceDefinition
+      metadata:
+        annotations:
+          description: Represents a CatalogSourceConfig.
+          displayName: Catalog Source Config
+        name: catalogsourceconfigs.marketplace.redhat.com
+      spec:
+        additionalPrinterColumns:
+        - JSONPath: .spec.targetNamespace
+          description: The namespace where the operators will be enabled
+          name: TargetNamespace
+          type: string
+        - JSONPath: .spec.packages
+          description: List of operator(s) which will be enabled in the target namespace
+          name: Packages
+          type: string
+        - JSONPath: .status.currentPhase.phase.name
+          description: Current status of the CatalogSourceConfig
+          name: Status
+          type: string
+        - JSONPath: .status.currentPhase.phase.message
+          description: Message associated with the current status
+          name: Message
+          type: string
+        - JSONPath: .metadata.creationTimestamp
+          name: Age
+          type: date
+        group: marketplace.redhat.com
+        names:
+          kind: CatalogSourceConfig
+          listKind: CatalogSourceConfigList
+          plural: catalogsourceconfigs
+          shortNames:
+          - csc
+          singular: catalogsourceconfig
+        scope: Namespaced
+        validation:
+          openAPIV3Schema:
+            properties:
+              spec:
+                description: Spec for a CatalogSourceConfig
+                properties:
+                  packages:
+                    description: Comma separated list of operator(s) without spaces
+                      which will be enabled in the target namespace
+                    type: string
+                  targetNamespace:
+                    description: The namespace where the operators will be enabled
+                    type: string
+                required:
+                - targetNamespace
+                - packages
+                type: object
+        version: v1alpha1
+    - apiVersion: apiextensions.k8s.io/v1beta1
+      kind: CustomResourceDefinition
+      metadata:
+        annotations:
+          description: Represents an OperatorSource.
+          displayName: Operator Source
+        name: operatorsources.marketplace.redhat.com
+      spec:
+        additionalPrinterColumns:
+        - JSONPath: .spec.type
+          description: The type of the OperatorSource
+          name: Type
+          type: string
+        - JSONPath: .spec.endpoint
+          description: The endpoint of the OperatorSource
+          name: Endpoint
+          type: string
+        - JSONPath: .spec.registryNamespace
+          description: App registry namespace
+          name: Registry
+          type: string
+        - JSONPath: .spec.displayName
+          description: Display (pretty) name to indicate the OperatorSource's name
+          name: DisplayName
+          type: string
+        - JSONPath: .spec.publisher
+          description: Publisher of the OperatorSource
+          name: Publisher
+          type: string
+        - JSONPath: .status.currentPhase.phase.name
+          description: Current status of the OperatorSource
+          name: Status
+          type: string
+        - JSONPath: .status.currentPhase.phase.message
+          description: Message associated with the current status
+          name: Message
+          type: string
+        - JSONPath: .metadata.creationTimestamp
+          name: Age
+          type: date
+        group: marketplace.redhat.com
+        names:
+          kind: OperatorSource
+          listKind: OperatorSourceList
+          plural: operatorsources
+          shortNames:
+          - opsrc
+          singular: operatorsource
+        scope: Namespaced
+        validation:
+          openAPIV3Schema:
+            properties:
+              spec:
+                description: Spec for an OperatorSource.
+                properties:
+                  endpoint:
+                    description: Points to the remote app registry server from where
+                      operator manifests can be fetched.
+                    type: string
+                  registryNamespace:
+                    description: 'The namespace in app registry.
+
+                      Only operator manifests under this namespace will be visible.
+
+                      Please note that this is not a k8s namespace.'
+                    type: string
+                  type:
+                    description: The type of the OperatorSource
+                    pattern: appregistry
+                    type: string
+                required:
+                - type
+                - endpoint
+                - registryNamespace
+                type: object
+        version: v1alpha1
+  packages: |
+    - channels:
+      - currentCSV: marketplace-operator.v0.0.1
+        name: alpha
+      packageName: marketplace
diff --git a/tests/test_files/bundles/verification/valid.bundle.yaml b/tests/test_files/bundles/verification/valid.bundle.yaml
index db7cea6..72f11da 100644
--- a/tests/test_files/bundles/verification/valid.bundle.yaml
+++ b/tests/test_files/bundles/verification/valid.bundle.yaml
@@ -107,6 +107,14 @@ data:
           mediatype: image/png
         install:
           spec:
+            permissions:
+            - rules:
+              - apiGroups:
+                - ''
+                resources:
+                - 'serviceaccounts'
+                verbs:
+                - '*'
             clusterPermissions:
             - rules:
               - apiGroups:
diff --git a/tests/test_validate.py b/tests/test_validate.py
index 806c430..73e41ea 100644
--- a/tests/test_validate.py
+++ b/tests/test_validate.py
@@ -30,6 +30,20 @@ def test_valid_bundles(bundle, expected_validation_results_dict):
     ("tests/test_files/bundles/verification/no-data-key.bundle.yaml",
         {'errors': ['Bundle does not contain any clusterServiceVersions.',
                     'Bundle does not contain any packages.'], 'warnings': []}),
+    ("tests/test_files/bundles/verification/csvinstallspecnotlists.invalid.bundle.yaml",
+        {'errors': ['csv spec.install.spec.deployments should be a list',
+                    'csv spec.install.spec.permissions should be a list',
+                    'csv spec.install.spec.clusterPermissions should be a list'],
+            'warnings': ['csv spec.icon not defined']}),
+    ("tests/test_files/bundles/verification/"
+        "csvmissinginstallattributes.invalid.bundle.yaml",
+        {'errors': ['csv spec.install.strategy not defined',
+                    'csv spec.install.spec not defined'],
+            'warnings': ['csv spec.icon not defined']}),
+    ("tests/test_files/bundles/verification/"
+        "csvinstallstrategywrongvalue.invalid.bundle.yaml",
+        {'errors': ["csv spec.install.strategy must be one of ['deployment']"],
+            'warnings': ['csv spec.icon not defined']}),
 ])
 def test_invalid_bundle(bundle, expected_validation_results_dict):
     valid, validation_results_dict = get_validation_results(bundle)

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov testfixtures
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi==2025.1.31
charset-normalizer==3.4.1
coverage==7.8.0
exceptiongroup==1.2.2
idna==3.10
iniconfig==2.1.0
-e git+https://github.com/operator-framework/operator-courier.git@5a4852c22f5de4d664ca1cc7da285e3e4972387b#egg=operator_courier
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
pytest-cov==6.0.0
PyYAML==6.0.2
requests==2.32.3
semver==3.0.4
testfixtures==8.3.0
tomli==2.2.1
urllib3==2.3.0
validators==0.34.0

name: operator-courier
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - coverage==7.8.0
      - exceptiongroup==1.2.2
      - idna==3.10
      - iniconfig==2.1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-cov==6.0.0
      - pyyaml==6.0.2
      - requests==2.32.3
      - semver==3.0.4
      - testfixtures==8.3.0
      - tomli==2.2.1
      - urllib3==2.3.0
      - validators==0.34.0
prefix: /opt/conda/envs/operator-courier

tests/test_validate.py::test_invalid_bundle[tests/test_files/bundles/verification/csvinstallspecnotlists.invalid.bundle.yaml-expected_validation_results_dict2] tests/test_validate.py::test_invalid_bundle[tests/test_files/bundles/verification/csvmissinginstallattributes.invalid.bundle.yaml-expected_validation_results_dict3] tests/test_validate.py::test_invalid_bundle[tests/test_files/bundles/verification/csvinstallstrategywrongvalue.invalid.bundle.yaml-expected_validation_results_dict4]
tests/test_validate.py::test_valid_bundles[tests/test_files/bundles/verification/noicon.valid.bundle.yaml-expected_validation_results_dict0] tests/test_validate.py::test_valid_bundles[tests/test_files/bundles/verification/nocrd.valid.bundle.yaml-expected_validation_results_dict1] tests/test_validate.py::test_invalid_bundle[tests/test_files/bundles/verification/nopkg.invalid.bundle.yaml-expected_validation_results_dict0] tests/test_validate.py::test_invalid_bundle[tests/test_files/bundles/verification/no-data-key.bundle.yaml-expected_validation_results_dict1] tests/test_validate.py::test_ui_valid_bundle_io[tests/test_files/bundles/verification/valid.bundle.yaml-expected_validation_results_dict0] tests/test_validate.py::test_ui_invalid_bundle_io[tests/test_files/bundles/verification/ui.invalid.bundle.yaml-expected_validation_results_dict0] tests/test_validate.py::test_valid_bundles_with_package_name_and_repo_name_match[tests/test_files/bundles/verification/valid.bundle.yaml-marketplace] tests/test_validate.py::test_valid_bundles_with_package_name_and_repo_name_match[tests/test_files/bundles/verification/nocrd.valid.bundle.yaml-svcat] tests/test_validate.py::test_valid_bundles_with_package_name_and_repo_name_mismatch[tests/test_files/bundles/verification/valid.bundle.yaml-wrong-repo-name] tests/test_validate.py::test_valid_bundles_with_package_name_and_repo_name_mismatch[tests/test_files/bundles/verification/nocrd.valid.bundle.yaml-wrong-repo-name] tests/test_validate.py::test_valid_bundles_with_multiple_packages[tests/test_files/bundles/verification/multiplepkgs.invalid.bundle.yaml] tests/test_validate.py::test_invalid_bundle_missing_fields[tests/test_files/bundles/verification/nopkg.invalid.bundle.yaml-logInfo0] tests/test_validate.py::test_invalid_bundle_missing_fields[tests/test_files/bundles/verification/crdmissingkindfield.invalid.bundle.yaml-logInfo1] tests/test_validate.py::test_invalid_bundle_missing_fields[tests/test_files/bundles/verification/crdmissingpluralfield.invalid.bundle.yaml-logInfo2] tests/test_validate.py::test_invalid_bundle_missing_fields[tests/test_files/bundles/verification/crdmissingversionfield.invalid.bundle.yaml-logInfo3] tests/test_validate.py::test_invalid_bundle_missing_fields[tests/test_files/bundles/verification/csvmissingkindfield.invalid.bundle.yaml-logInfo4] tests/test_validate.py::test_invalid_bundle_missing_fields[tests/test_files/bundles/verification/csvmissingnamefield.invalid.bundle.yaml-logInfo5] tests/test_validate.py::test_invalid_bundle_missing_fields[tests/test_files/bundles/verification/csvmissingversionfield.invalid.bundle.yaml-logInfo6] tests/test_validate.py::test_invalid_bundle_crd_csv_fields_mismatch[tests/test_files/bundles/verification/csvcrdfieldmismatch1.invalid.bundle.yaml-logInfo0] tests/test_validate.py::test_invalid_bundle_crd_csv_fields_mismatch[tests/test_files/bundles/verification/csvcrdfieldmismatch2.invalid.bundle.yaml-logInfo1] tests/test_validate.py::test_invalid_bundle_crd_csv_fields_mismatch[tests/test_files/bundles/verification/csvcrdfieldmismatch3.invalid.bundle.yaml-logInfo2]
operatorcourier/validate.py
operatorcourier/validate.py