From 2d39f3f96cfbf72e65ed95784542829b2d531ee7 Mon Sep 17 00:00:00 2001
From: Leif Madsen <lmadsen@redhat.com>
Date: Fri, 13 Mar 2020 12:49:24 -0400
Subject: [PATCH] Create stable channel and 1.0.0 release (#44)

* Create stable channel and 1.0.0 release

Create a new channel called stable which will host the 1.0.0
release of Smart Gateway Operator.

* Set Smart Gateway container image from env var

Setting the container image for the Smart Gateway from an environment variable allows
for setting a specific version of the Smart Gateway to come up, allowing versions to
be tied to the Operator container image itself, and thus a CSV version.

Looking at other Operators, any dependent images seem to get set via environment variable
on the Operator, and then used for instantiating the desired set of images for that CSV.

If the SMARTGATEWAY_IMAGE environment variable is not set, then the default is to use
the latest image from quay.io/infrawatch/smart-gateway.

* Don't reference beta1 in semver

* Only release on tagged versions
---
 .osdk-scorecard.yaml                          |   6 +-
 .travis.yml                                   |   5 +-
 README.md                                     | 165 ++++++++--
 build/Dockerfile                              |   2 +-
 build/metadata.sh                             |   4 +
 build/new_csv_version.sh                      |  23 ++
 build/push_app2quay.sh                        |   5 +-
 build/travis/after_success.sh                 |  22 +-
 build/update_csv.sh                           |   4 +-
 ...gateway.infra.watch_smartgateways_crd.yaml |   2 +-
 ...operator.v0.2.0.clusterserviceversion.yaml |   2 +-
 .../{ => 1.0.0}/Dockerfile                    |   6 +-
 .../{ => 1.0.0}/metadata/annotations.yaml     |   6 +-
 ...operator.v1.0.0.clusterserviceversion.yaml | 296 ++++++++++++++++++
 ...gateway.infra.watch_smartgateways_crd.yaml | 115 +++++++
 .../smart-gateway-operator.package.yaml       |   6 +-
 deploy/operator.yaml                          |   2 +
 deploy/operator_group.yaml                    |   8 +
 deploy/role.yaml                              |   5 +-
 roles/smartgateway/defaults/main.yml          |   2 +-
 roles/smartgateway/tasks/main.yml             |  37 +--
 roles/smartgateway/tasks/service.yml          |  19 --
 .../smartgateway/templates/deployment.yaml.j2 |  16 +-
 roles/smartgateway/templates/service.yaml.j2  |  17 +
 24 files changed, 677 insertions(+), 98 deletions(-)
 create mode 100644 build/metadata.sh
 create mode 100755 build/new_csv_version.sh
 rename deploy/olm-catalog/smart-gateway-operator/{ => 1.0.0}/Dockerfile (60%)
 rename deploy/olm-catalog/smart-gateway-operator/{ => 1.0.0}/metadata/annotations.yaml (52%)
 create mode 100644 deploy/olm-catalog/smart-gateway-operator/1.0.0/smart-gateway-operator.v1.0.0.clusterserviceversion.yaml
 create mode 100644 deploy/olm-catalog/smart-gateway-operator/1.0.0/smartgateway.infra.watch_smartgateways_crd.yaml
 create mode 100644 deploy/operator_group.yaml
 delete mode 100644 roles/smartgateway/tasks/service.yml
 create mode 100644 roles/smartgateway/templates/service.yaml.j2

diff --git a/.osdk-scorecard.yaml b/.osdk-scorecard.yaml
index 6462f6f..194e511 100644
--- a/.osdk-scorecard.yaml
+++ b/.osdk-scorecard.yaml
@@ -1,11 +1,13 @@
 scorecard:
-  # Setting a global scorecard option
+  version: v1alpha2
   output: text
+  bundle: deploy/olm-catalog/smart-gateway-operator/1.0.0/metadata
   plugins:
     - basic:
         cr-manifest:
           - "deploy/crds/smartgateway.infra.watch_v2alpha1_smartgateway.metrics_cr.yaml"
+        csv-path: "deploy/olm-catalog/smart-gateway-operator/1.0.0/smart-gateway-operator.v1.0.0.clusterserviceversion.yaml"
     - olm:
         cr-manifest:
           - "deploy/crds/smartgateway.infra.watch_v2alpha1_smartgateway.metrics_cr.yaml"
-        csv-path: "deploy/olm-catalog/smart-gateway-operator/0.2.0/smart-gateway-operator.v0.2.0.clusterserviceversion.yaml"
+        csv-path: "deploy/olm-catalog/smart-gateway-operator/1.0.0/smart-gateway-operator.v1.0.0.clusterserviceversion.yaml"
diff --git a/.travis.yml b/.travis.yml
index 20dc615..a281d31 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,7 +13,4 @@ script:
 - operator-courier verify --ui_validate_io deploy/olm-catalog/smart-gateway-operator
 - ansible-lint roles/smartgateway/
 after_success:
-- export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH;
-  else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
-- echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH"
-- "./build/travis/after_success.sh"
+- if [ "$TRAVIS_TAG" == "" ]; then echo "Not a tagged release, skipping after_success.sh"; else ./build/travis/after_success.sh; fi
diff --git a/README.md b/README.md
index ab3e5f5..c7f3939 100644
--- a/README.md
+++ b/README.md
@@ -26,45 +26,174 @@ development is available at https://github.com/code-ready/crc.
 A procedure for testing in CodeReady Containers will be available soon.
 
 * buildah
-  * 1.12.0
+  * 1.14.0
 * kubernetes
-  * v1.14.0
+  * v1.16.2
 * crc
-  * crc version: 1.3.0+918756b
+  * crc version: 1.6.0+8ef676f
 * oc
   * openshift-clients-4.2.0-201910041700
 * operator-sdk
-  * v0.12.0 (!0.13.0 which causes regressions via `gen-csv` command)
+  * v0.15.2 (!0.13.0 which causes regressions via `gen-csv` command)
 
-### Set up crc and buildah
+### Set up CRC and buildah
 
-<todo>
+Setup CRC and then login with the `kubeadmin` user.
+
+```
+$ crc setup
+$ crc start --memory=32768
+$ crc console --credentials
+```
+
+Install `buildah` via `dnf`.
+
+```
+sudo dnf install buildah -y
+```
+
+### Login to CRC registry
+
+```
+REGISTRY=$(oc registry info)
+TOKEN=$(oc whoami -t)
+INTERNAL_REGISTRY=$(oc registry info --internal=true)
+buildah login --tls-verify=false -u openshift -p "${TOKEN}" "${REGISTRY}"
+```
 
 ### Build the operator
 
-<todo>
+```
+buildah bud -f build/Dockerfile -t "${REGISTRY}/default/smart-gateway-operator:latest" .
+buildah push --tls-verify=false "${REGISTRY}/default/smart-gateway-operator:latest"
+```
 
 ### Deploy with the newly built operator
 
-<todo>
+Install required RBAC rules and service account.
 
-### FIXME - Unit testing
+```
+oc apply \
+    -f deploy/role_binding.yaml \
+    -f deploy/role.yaml \
+    -f deploy/service_account.yaml \
+    -f deploy/operator_group.yaml
+```
 
-With molecule (Currently broken)
+Pick a version from `deploy/olm-catalog/smart-gateway-operator/` and run the
+following commands. Adjust version to what you want to test. We'll be using
+`v1.0.0` as our example version.
 
-### Integration testing
+```
+CSV_VERSION=1.0.0
+INTERNAL_REGISTRY=$(oc registry info --internal=true)
+oc apply -f deploy/olm-catalog/smart-gateway-operator/${CSV_VERSION}/smartgateway.infra.watch_smartgateways_crd.yaml
+
+oc create -f <(sed "\
+    s|image: .\+/smart-gateway-operator:.\+$|image: ${INTERNAL_REGISTRY}/default/smart-gateway-operator:latest|g;
+    s|namespace: placeholder|namespace: default|g"\
+    "deploy/olm-catalog/smart-gateway-operator/${CSV_VERSION}/smart-gateway-operator.v${CSV_VERSION}.clusterserviceversion.yaml")
+```
 
-Test the newly built operator with the Service Telemetry Framework (STF).
+Validate that installation of the `ClusterServiceVersion` is progressing via
+the `oc` CLI console.
+```
+oc get csv --watch
+```
+If you see `PHASE: Succeeded` then your CSV has been properly imported and
+your Operator should be running locally. You can validate this by running `oc
+get pods` and looking for the `smart-gateway-operator` and that it is
+`Running`.
 
-<todo>
+You can bring up the logs of the Smart Gateway Operator by running `oc logs
+<<pod_name>> -c operator`.
 
 ## Creating a Smart Gateway
 
-<update>
+To create a Smart Gateway, you'll need to connect it to a compatible AMQP 1.x
+message bus. For demonstration purposes we're going to use the Red Hat AMQ
+Interconnect Operator, create an AMQ Interconnect instance, then create a Smart
+Gateway instance that connects to it.
+
+### Create AMQ Interconnect Subscription
+
+```
+oc apply -f - <<EOF
+apiVersion: operators.coreos.com/v1alpha1
+kind: Subscription
+metadata:
+  name: amq7-interconnect-operator
+  namespace: default
+spec:
+  channel: 1.2.0
+  installPlanApproval: Automatic
+  name: amq7-interconnect-operator
+  source: redhat-operators
+  sourceNamespace: openshift-marketplace
+EOF
+```
 
-Start a new smart gateway by creating a CustomResource object
-based on the example:
+You can check the status of the AMQ Interconnect ClusterServiceVersion
+installation with `oc get csv`. When complete you should see `PHASE:
+Succeeded`.
 
-```shell
-oc create -f deploy/crds/smartgateway.infra.watch_v2alpha1_smartgateway.metrics_cr.yaml
+### Create AMQ Interconnect Instance
+
+```
+oc apply -f - <<EOF
+apiVersion: interconnectedcloud.github.io/v1alpha1
+kind: Interconnect
+metadata:
+  name: amq-interconnect
+  namespace: default
+spec:
+  addresses:
+  - distribution: closest
+    prefix: closest
+  - distribution: multicast
+    prefix: multicast
+  - distribution: closest
+    prefix: unicast
+  - distribution: closest
+    prefix: exclusive
+  - distribution: multicast
+    prefix: broadcast
+  deploymentPlan:
+    livenessPort: 8888
+    placement: Any
+    resources: {}
+    role: interior
+    size: 2
+  edgeListeners:
+  - port: 45672
+  interRouterListeners:
+  - port: 55672
+  listeners:
+  - port: 5672
+  - authenticatePeer: true
+    expose: true
+    http: true
+    port: 8080
+  users: amq-interconnect-users
+EOF
+```
+
+Validate that you see both AMQ Interconnect routers come up with `oc get pods`.
+
+### Create Smart Gateway Instance
+
+```
+oc apply -f - <<EOF
+apiVersion: smartgateway.infra.watch/v2alpha1
+kind: SmartGateway
+metadata:
+  name: cloud1-metrics
+  namespace: default
+spec:
+  amqpUrl: amq-interconnect:5672/collectd/telemetry
+  debug: true
+  prefetch: 15000
+  serviceType: metrics
+  size: 1
+EOF
 ```
diff --git a/build/Dockerfile b/build/Dockerfile
index d5f272d..39dcb6e 100644
--- a/build/Dockerfile
+++ b/build/Dockerfile
@@ -1,4 +1,4 @@
-FROM quay.io/operator-framework/ansible-operator:v0.12.0
+FROM quay.io/operator-framework/ansible-operator:v0.14.1
 
 COPY roles/ ${HOME}/roles/
 COPY watches.yaml ${HOME}/watches.yaml
diff --git a/build/metadata.sh b/build/metadata.sh
new file mode 100644
index 0000000..d7c1606
--- /dev/null
+++ b/build/metadata.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+CSV_VERSION=${CSV_VERSION:-1.0.0}
+UNIXDATE=$(date +%s)
+ORGANIZATION=${ORGANIZATION:-infrawatch}
diff --git a/build/new_csv_version.sh b/build/new_csv_version.sh
new file mode 100755
index 0000000..cc825e6
--- /dev/null
+++ b/build/new_csv_version.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env sh
+
+if [ -z "$CSV_VERSION" ]; then
+    echo -n "CSV version to create [e.g. 1.1.0]: "
+    read CSV_VERSION
+fi
+
+if [ -z "$FROM_VERSION" ]; then
+    echo -n "CSV version to upgrade from [e.g. 1.0.0]: "
+    read FROM_VERSION
+fi
+
+if [ -z "$CSV_CHANNEL" ]; then
+    echo -n "CSV channel to publish to [e.g. stable]: "
+    read CSV_CHANNEL
+fi
+
+
+operator-sdk generate csv --csv-version=${CSV_VERSION} \
+    --from-version=${FROM_VERSION}  \
+    --operator-name smart-gateway-operator \
+    --update-crds \
+    --csv-channel="${CSV_CHANNEL}"
diff --git a/build/push_app2quay.sh b/build/push_app2quay.sh
index 677db95..5b170ed 100755
--- a/build/push_app2quay.sh
+++ b/build/push_app2quay.sh
@@ -2,10 +2,7 @@
 # contents of this file originally from https://redhat-connect.gitbook.io/certified-operator-guide/ocp-deployment/openshift-deployment
 
 set -e
-
-CSV_VERSION=${CSV_VERSION:-0.2.0}
-UNIXDATE=$(date +%s)
-ORGANIZATION=${ORGANIZATION:-infrawatch}
+REL=$(dirname "$0"); source "${REL}/metadata.sh"
 
 if [ -z "$USERNAME" ]; then
     echo -n "Username: "
diff --git a/build/travis/after_success.sh b/build/travis/after_success.sh
index b9e4b7b..da9b1bc 100755
--- a/build/travis/after_success.sh
+++ b/build/travis/after_success.sh
@@ -2,19 +2,13 @@
 
 # Fail on error
 set -e
-
 REL=$(dirname "$0")
 
-# Add everything, get ready for commit. But only do it if we're on master or a
-# named branch of the format <#>.<#>.X. If you want to deploy on different
-# branches, you can change this.
-if [[ "$BRANCH" =~ ^master$|^[0-9]+\.[0-9]+\.X$ ]]; then
-    echo "Branch is master, so push new application to Quay registry"
-    export PATH=$HOME/bin:$PATH
-    curl -L https://github.com/operator-framework/operator-sdk/releases/download/v0.15.2/operator-sdk-v0.15.2-x86_64-linux-gnu -o $HOME/bin/operator-sdk
-    chmod +x $HOME/bin/operator-sdk
-    ${REL}/../update_csv.sh
-    ${REL}/../push_app2quay.sh
-else
-    echo "Not on master, so won't push new application artifacts"
-fi
+echo "Pushing new application to Quay registry"
+export PATH=$HOME/bin:$PATH
+curl -L https://github.com/operator-framework/operator-sdk/releases/download/v0.15.2/operator-sdk-v0.15.2-x86_64-linux-gnu -o "$HOME/bin/operator-sdk"
+chmod +x "$HOME/bin/operator-sdk"
+
+# Push new application version, but strip the first character which is expected to be 'v'
+# Why not just create tags that don't have 'v'? Because the container image versions are expected to lead with a 'v'. Fun!
+CSV_VERSION="${TRAVIS_TAG:1}" "${REL}/../push_app2quay.sh""
diff --git a/build/update_csv.sh b/build/update_csv.sh
index 555101a..c2ac411 100755
--- a/build/update_csv.sh
+++ b/build/update_csv.sh
@@ -1,2 +1,4 @@
 #!/usr/bin/env sh
-operator-sdk generate csv --csv-version 0.2.0 --operator-name smart-gateway-operator --update-crds
+set -e
+REL=$(dirname "$0"); source "${REL}/metadata.sh"
+operator-sdk generate csv --csv-version=${CSV_VERSION} --operator-name smart-gateway-operator --update-crds
diff --git a/deploy/crds/smartgateway.infra.watch_smartgateways_crd.yaml b/deploy/crds/smartgateway.infra.watch_smartgateways_crd.yaml
index f026c0d..244f272 100644
--- a/deploy/crds/smartgateway.infra.watch_smartgateways_crd.yaml
+++ b/deploy/crds/smartgateway.infra.watch_smartgateways_crd.yaml
@@ -89,7 +89,7 @@ spec:
               type: integer
             containerImagePath:
               description: Path to the container image this Operator will deploy. Value is defined as the standard registry/image_name:tag
-                format. Defaults to 'quay.io/infrawatch/smart-gateway:latest'
+                format.
               type: string
             useTimestamp:
               description: Use the source timestamp (time when data was collected) rather than let Prometheus write when the data was 
diff --git a/deploy/olm-catalog/smart-gateway-operator/0.2.0/smart-gateway-operator.v0.2.0.clusterserviceversion.yaml b/deploy/olm-catalog/smart-gateway-operator/0.2.0/smart-gateway-operator.v0.2.0.clusterserviceversion.yaml
index d953906..33c44ac 100644
--- a/deploy/olm-catalog/smart-gateway-operator/0.2.0/smart-gateway-operator.v0.2.0.clusterserviceversion.yaml
+++ b/deploy/olm-catalog/smart-gateway-operator/0.2.0/smart-gateway-operator.v0.2.0.clusterserviceversion.yaml
@@ -281,7 +281,7 @@ spec:
     name: smart-gateway-operator
   links:
   - name: Source Code
-    url: https://github.com/infrawatch/smart-gateway-operator.0.2.0
+    url: https://github.com/infrawatch/smart-gateway-operator
   maintainers:
   - email: support@redhat.com
     name: Red Hat CloudOps DFG
diff --git a/deploy/olm-catalog/smart-gateway-operator/Dockerfile b/deploy/olm-catalog/smart-gateway-operator/1.0.0/Dockerfile
similarity index 60%
rename from deploy/olm-catalog/smart-gateway-operator/Dockerfile
rename to deploy/olm-catalog/smart-gateway-operator/1.0.0/Dockerfile
index 4e3bd52..1896256 100644
--- a/deploy/olm-catalog/smart-gateway-operator/Dockerfile
+++ b/deploy/olm-catalog/smart-gateway-operator/1.0.0/Dockerfile
@@ -1,11 +1,11 @@
 FROM scratch
 
-LABEL operators.operatorframework.io.bundle.mediatype.v1=plain
+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=smart-gateway-operator
-LABEL operators.operatorframework.io.bundle.channels.v1=alpha
-LABEL operators.operatorframework.io.bundle.channel.default.v1=alpha
+LABEL operators.operatorframework.io.bundle.channels.v1=stable
+LABEL operators.operatorframework.io.bundle.channel.default.v1=stable
 
 COPY /*.yaml /manifests/
 COPY /metadata/annotations.yaml /metadata/annotations.yaml
diff --git a/deploy/olm-catalog/smart-gateway-operator/metadata/annotations.yaml b/deploy/olm-catalog/smart-gateway-operator/1.0.0/metadata/annotations.yaml
similarity index 52%
rename from deploy/olm-catalog/smart-gateway-operator/metadata/annotations.yaml
rename to deploy/olm-catalog/smart-gateway-operator/1.0.0/metadata/annotations.yaml
index d0a4ecf..4fb85ad 100644
--- a/deploy/olm-catalog/smart-gateway-operator/metadata/annotations.yaml
+++ b/deploy/olm-catalog/smart-gateway-operator/1.0.0/metadata/annotations.yaml
@@ -1,7 +1,7 @@
 annotations:
-  operators.operatorframework.io.bundle.channel.default.v1: alpha
-  operators.operatorframework.io.bundle.channels.v1: alpha
+  operators.operatorframework.io.bundle.channel.default.v1: stable
+  operators.operatorframework.io.bundle.channels.v1: stable
   operators.operatorframework.io.bundle.manifests.v1: manifests/
-  operators.operatorframework.io.bundle.mediatype.v1: plain
+  operators.operatorframework.io.bundle.mediatype.v1: registry+v1
   operators.operatorframework.io.bundle.metadata.v1: metadata/
   operators.operatorframework.io.bundle.package.v1: smart-gateway-operator
diff --git a/deploy/olm-catalog/smart-gateway-operator/1.0.0/smart-gateway-operator.v1.0.0.clusterserviceversion.yaml b/deploy/olm-catalog/smart-gateway-operator/1.0.0/smart-gateway-operator.v1.0.0.clusterserviceversion.yaml
new file mode 100644
index 0000000..4cdc7db
--- /dev/null
+++ b/deploy/olm-catalog/smart-gateway-operator/1.0.0/smart-gateway-operator.v1.0.0.clusterserviceversion.yaml
@@ -0,0 +1,296 @@
+apiVersion: operators.coreos.com/v1alpha1
+kind: ClusterServiceVersion
+metadata:
+  annotations:
+    alm-examples: |-
+      [
+        {
+          "apiVersion": "smartgateway.infra.watch/v2alpha1",
+          "kind": "SmartGateway",
+          "metadata": {
+            "name": "cloud1-events"
+          },
+          "spec": {
+            "debug": false,
+            "prefetch": 0,
+            "resetIndex": false,
+            "serviceType": "events",
+            "size": 1
+          }
+        },
+        {
+          "apiVersion": "smartgateway.infra.watch/v2alpha1",
+          "kind": "SmartGateway",
+          "metadata": {
+            "name": "cloud1-metrics"
+          },
+          "spec": {
+            "debug": false,
+            "prefetch": 15000,
+            "serviceType": "metrics",
+            "size": 1,
+            "useTimestamp": true
+          }
+        }
+      ]
+    capabilities: Basic Install
+    categories: Monitoring
+    certified: "false"
+    containerImage: quay.io/infrawatch/smart-gateway-operator:v1.0.0
+    createdAt: "2019-11-14T14:49:00Z"
+    description: Smart Gateway Operator
+    repository: https://github.com/infrawatch/smart-gateway-operator
+    support: Red Hat (CloudOps)
+  name: smart-gateway-operator.v1.0.0
+  namespace: placeholder
+spec:
+  apiservicedefinitions: {}
+  customresourcedefinitions:
+    owned:
+    - description: Instance of the Smart Gateway
+      displayName: SmartGateway
+      kind: SmartGateway
+      name: smartgateways.smartgateway.infra.watch
+      resources:
+      - kind: Pod
+        name: ""
+        version: v1
+      - kind: Deployments
+        name: ""
+        version: v1
+      - kind: ReplicaSets
+        name: ""
+        version: v1
+      - kind: Services
+        name: ""
+        version: v1
+      - kind: ConfigMaps
+        name: ""
+        version: v1
+      - kind: SmartGateways
+        name: ""
+        version: v2alpha1
+      specDescriptors:
+      - description: Number of Smart Gateways to deploy
+        displayName: Size
+        path: size
+        x-descriptors:
+        - urn:alm:descriptor:com.tectonic.ui:number
+      - description: Location of the AMQP endpoint to connect the Smart Gateway to
+        displayName: AMQP URL
+        path: amqpUrl
+        x-descriptors:
+        - urn:alm:descriptor:com.tectonic.ui:text
+      - description: Container image path
+        displayName: Container image path
+        path: containerImagePath
+        x-descriptors:
+        - urn:alm:descriptor:com.tectonic.ui:text
+      - description: Number of messages that we can prefetch from AMQP 1.x. By enabling
+          prefetching, the smart gateway won't need to request every message individually
+          from the AMQP bus, resulting in a round trip for every request between sender
+          and receiver. To avoid the round trip for every message, the use of prefetch
+          can be used to allow the receiver to request messages be sent in anticipation
+          of them being sent to us.
+        displayName: Prefetch
+        path: prefetch
+        x-descriptors:
+        - urn:alm:descriptor:com.tectonic.ui:number
+      - description: Use the source timestamp (time when data was collected) rather
+          than let Prometheus write when the data was scraped for that metric.
+        displayName: Use Timestamp
+        path: useTimestamp
+        x-descriptors:
+        - urn:alm:descriptor:com.tectonic.ui:booleanSwitch
+      - description: Smart Gateway Service Type
+        displayName: Service Type
+        path: serviceType
+        x-descriptors:
+        - urn:alm:descriptor:com.tectonic.ui:select:metrics
+        - urn:alm:descriptor:com.tectonic.ui:select:events
+      - description: Enable additional debugging information to console output
+        displayName: Enable debugging
+        path: debug
+        x-descriptors:
+        - urn:alm:descriptor:tectonic.ui:booleanSwitch
+      statusDescriptors:
+      - description: Conditions provided by deployment
+        displayName: Conditions
+        path: conditions
+        x-descriptors:
+        - urn:alm:descriptor:io.kubernetes.conditions
+      version: v2alpha1
+  description: |-
+    # Smart Gateway for Service Telemetry Framework
+
+    The Smart Gateway is middleware for OpenShift that takes metrics and events
+    data streams from an AMQP 1.x message bus, and provides a method to having
+    that data stream stored within Prometheus or ElasticSearch.
+
+    ## Core capabilities
+
+    The Smart Gateway provides two modes:
+
+    * metrics: provides an HTTP scrape endpoint for Prometheus
+    * events: writes events directly to an ElasticSearch endpoint
+
+    ## Operator features
+
+    * **Two Service Types** - Supports the `metrics` and `events` service types which defines the type of Smart Gateway to be deployed
+
+    * **Configuration** - Configuration of the Smart Gateway to allow for it to be connected to an AMQP 1.x bus and pointed at the appropriate storage mechanism based on service type.
+
+    ## Before getting started
+
+    1. Ensure an AMQP 1.x bus has been setup (such as AMQ Interconnect)
+    2. If the Smart Gateway is running in events mode, be sure the ElasticSearch Operator and ElasticSearch instance have been pre-deployed.
+  displayName: Smart Gateway Operator
+  icon:
+  - base64data: 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
+    mediatype: image/png
+  install:
+    spec:
+      deployments:
+      - name: smart-gateway-operator
+        spec:
+          replicas: 1
+          selector:
+            matchLabels:
+              app: smart-gateway-operator
+          strategy: {}
+          template:
+            metadata:
+              labels:
+                app: smart-gateway-operator
+            spec:
+              containers:
+              - command:
+                - /usr/local/bin/ao-logs
+                - /tmp/ansible-operator/runner
+                - stdout
+                image: quay.io/infrawatch/smart-gateway-operator:v1.0.0
+                imagePullPolicy: Always
+                name: ansible
+                resources: {}
+                volumeMounts:
+                - mountPath: /tmp/ansible-operator/runner
+                  name: runner
+                  readOnly: true
+              - env:
+                - name: WATCH_NAMESPACE
+                  valueFrom:
+                    fieldRef:
+                      fieldPath: metadata.annotations['olm.targetNamespaces']
+                - name: POD_NAME
+                  valueFrom:
+                    fieldRef:
+                      fieldPath: metadata.name
+                - name: OPERATOR_NAME
+                  value: smart-gateway-operator
+                - name: ANSIBLE_GATHERING
+                  value: explicit
+                - name: SMARTGATEWAY_IMAGE
+                  value: quay.io/infrawatch/smart-gateway:v2.0.0-beta1
+                image: quay.io/infrawatch/smart-gateway-operator:v1.0.0
+                imagePullPolicy: Always
+                name: operator
+                resources: {}
+                volumeMounts:
+                - mountPath: /tmp/ansible-operator/runner
+                  name: runner
+              serviceAccountName: smart-gateway-operator
+              volumes:
+              - emptyDir: {}
+                name: runner
+      permissions:
+      - rules:
+        - apiGroups:
+          - ""
+          resources:
+          - pods
+          - services
+          - endpoints
+          - persistentvolumeclaims
+          - events
+          - configmaps
+          - secrets
+          verbs:
+          - '*'
+        - apiGroups:
+          - ""
+          resources:
+          - namespaces
+          verbs:
+          - get
+        - apiGroups:
+          - extensions
+          resources:
+          - deployments
+          verbs:
+          - '*'
+        - apiGroups:
+          - apps
+          resources:
+          - deployments
+          - daemonsets
+          - replicasets
+          - statefulsets
+          verbs:
+          - '*'
+        - apiGroups:
+          - monitoring.coreos.com
+          resources:
+          - servicemonitors
+          verbs:
+          - get
+          - create
+          - list
+          - patch
+          - watch
+        - apiGroups:
+          - apps
+          resourceNames:
+          - smart-gateway-operator
+          resources:
+          - deployments/finalizers
+          verbs:
+          - update
+        - apiGroups:
+          - smartgateway.infra.watch
+          resources:
+          - '*'
+          verbs:
+          - '*'
+        serviceAccountName: smart-gateway-operator
+    strategy: deployment
+  installModes:
+  - supported: true
+    type: OwnNamespace
+  - supported: true
+    type: SingleNamespace
+  - supported: false
+    type: MultiNamespace
+  - supported: true
+    type: AllNamespaces
+  keywords:
+  - servicetelemetry
+  - monitoring
+  - telemetry
+  - notifications
+  - smartgateway
+  labels:
+    name: smart-gateway-operator
+  links:
+  - name: Source Code
+    url: https://github.com/infrawatch/smart-gateway-operator
+  maintainers:
+  - email: support@redhat.com
+    name: Red Hat CloudOps DFG
+  maturity: alpha
+  provider:
+    name: Red Hat, Inc.
+  replaces: smart-gateway-operator.v0.2.0
+  selector:
+    matchLabels:
+      name: smart-gateway-operator
+  version: 1.0.0
diff --git a/deploy/olm-catalog/smart-gateway-operator/1.0.0/smartgateway.infra.watch_smartgateways_crd.yaml b/deploy/olm-catalog/smart-gateway-operator/1.0.0/smartgateway.infra.watch_smartgateways_crd.yaml
new file mode 100644
index 0000000..244f272
--- /dev/null
+++ b/deploy/olm-catalog/smart-gateway-operator/1.0.0/smartgateway.infra.watch_smartgateways_crd.yaml
@@ -0,0 +1,115 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: smartgateways.smartgateway.infra.watch
+spec:
+  group: smartgateway.infra.watch
+  names:
+    kind: SmartGateway
+    listKind: SmartGatewayList
+    plural: smartgateways
+    singular: smartgateway
+  scope: Namespaced
+  version: v2alpha1
+  subresources:
+    status: {}
+  versions:
+  - name: v2alpha1
+    served: true
+    storage: true
+  validation:
+    openAPIV3Schema:
+      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://github.com/kubernetes/community/blob/master/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://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+          type: string
+        spec:
+          description: 'SmartGatewaySpec is a specification of the desired behavior
+            of the Smartgateway deployment. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status'
+          properties:
+            size:
+              description: Size sets the number of replicas to create. Defaults to 1.
+              type: integer
+            amqpUrl:
+              description: AMQP1.x listener example 127.0.0.1:5672/collectd/telemetry. Defaults to using
+                'messaging-internal-<name>.<namespace>.src:5672/collectd/telemetry'.
+              type: string
+            amqpDataSource:
+              description: The expected data source of the messages received from the address configured in amqpUrl. Available values include 'universal', 'collectd', and 'ceilometer'.
+              type: string
+            useBasicAuth:
+              description: Whether to use basic authentication or not when connecting to ElasticSearch. Default is 'false'
+              type: boolean
+            elasticUrl:
+              description: URL for ElasticSearch endpoing to connect when the Smart Gateway is operating as an 'events' service type.
+                Defaults to 'elasticsearch-es-http.<namespace>.svc:9200'.
+              type: string
+            elasticUser:
+              description: Basic Authentication username for ElasticSearch.
+              type: string
+            elasticPass:
+              description: Basic Authentication password for ElasticSearch.
+              type: string
+            tlsSecretName:
+              description: Name of the Secret object that holds the TLS certificates and key for Elasticsearch.
+                Defaults to 'elasticsearch-es-cert'.
+            resetIndex:
+              description: Reset the ElasticSearch index on load. Defaults to 'false'.
+              type: boolean
+            serviceType:
+              description: The service type for this smart gateway. One of 'metrics' or 'events'. Defaults to 'metrics'.
+              type: string
+            exporterHost:
+              description: Metrics URL for Prometheus to export. Defaults to "0.0.0.0".
+              type: string
+            exporterPort:
+              description: Metrics port for Prometheus to export. Defaults to 8081.
+              type: integer
+            cpuStats:
+              description: Include CPU usage info in http requests (degrades performance). Defaults to 'false'.
+              type: boolean
+            dataCount:
+              description: Stop after receiving this many messages in total (-1 forever). Defaults to '-1'.
+              type: integer
+            debug:
+              description: Enable verbose debugging statements. Defaults to 'false'.
+              type: boolean
+            prefetch:
+              description: Number of messages that we can prefetch from AMQP 1.x. By enabling prefetching, the smart gateway won't need to
+                request every message individually from the AMQP bus, resulting in a round trip for every request between sender and receiver.
+                To avoid the round trip for every message, the use of prefetch can be used to allow the receiver to request messages be sent
+                in anticipation of them being sent to us.
+              type: integer
+            containerImagePath:
+              description: Path to the container image this Operator will deploy. Value is defined as the standard registry/image_name:tag
+                format.
+              type: string
+            useTimestamp:
+              description: Use the source timestamp (time when data was collected) rather than let Prometheus write when the data was 
+                scraped for that metric.
+              type: boolean
+        status:
+          description: Status results of an instance of Smart Gateway
+          properties:
+            conditions:
+              description: The resulting conditions when a Smart Gateway is instantiated
+              items:
+                properties:
+                  status:
+                    type: string
+                  type:
+                    type: string
+                  reason:
+                    type: string
+                  lastTransitionTime:
+                    type: string
+                type: object
+              type: array
+          type: object
diff --git a/deploy/olm-catalog/smart-gateway-operator/smart-gateway-operator.package.yaml b/deploy/olm-catalog/smart-gateway-operator/smart-gateway-operator.package.yaml
index 92308b9..fad7d6e 100644
--- a/deploy/olm-catalog/smart-gateway-operator/smart-gateway-operator.package.yaml
+++ b/deploy/olm-catalog/smart-gateway-operator/smart-gateway-operator.package.yaml
@@ -1,5 +1,5 @@
 channels:
-- currentCSV: smart-gateway-operator.v0.2.0
-  name: alpha
-defaultChannel: alpha
+- currentCSV: smart-gateway-operator.v1.0.0
+  name: stable
+defaultChannel: stable
 packageName: smartgateway-operator
diff --git a/deploy/operator.yaml b/deploy/operator.yaml
index 8a398a0..97cb92b 100644
--- a/deploy/operator.yaml
+++ b/deploy/operator.yaml
@@ -44,6 +44,8 @@ spec:
               value: "smart-gateway-operator"
             - name: ANSIBLE_GATHERING
               value: explicit
+            - name: SMARTGATEWAY_IMAGE
+              value: quay.io/infrawatch/smart-gateway:latest
       volumes:
         - name: runner
           emptyDir: {}
diff --git a/deploy/operator_group.yaml b/deploy/operator_group.yaml
new file mode 100644
index 0000000..85eba9a
--- /dev/null
+++ b/deploy/operator_group.yaml
@@ -0,0 +1,8 @@
+apiVersion: operators.coreos.com/v1
+kind: OperatorGroup
+metadata:
+  name: smartgateway-operator-group
+  namespace: default
+spec:
+  targetNamespaces:
+  - default
diff --git a/deploy/role.yaml b/deploy/role.yaml
index 0ff50e9..096e902 100644
--- a/deploy/role.yaml
+++ b/deploy/role.yaml
@@ -23,9 +23,9 @@ rules:
   verbs:
   - get
 - apiGroups:
-  - apps.openshift.io
+  - extensions
   resources:
-  - deploymentconfigs
+  - deployments
   verbs:
   - '*'
 - apiGroups:
@@ -53,7 +53,6 @@ rules:
   - smart-gateway-operator
   resources:
   - deployments/finalizers
-  - deploymentconfigs/finalizers
   verbs:
   - update
 - apiGroups:
diff --git a/roles/smartgateway/defaults/main.yml b/roles/smartgateway/defaults/main.yml
index 59deb88..cfdc3e9 100644
--- a/roles/smartgateway/defaults/main.yml
+++ b/roles/smartgateway/defaults/main.yml
@@ -1,7 +1,7 @@
 ---
 # defaults file for smartgateway
 size: 1
-container_image_path: quay.io/infrawatch/smart-gateway:latest
+state: present
 prometheus_scrape_interval: 1s
 use_basic_auth: false
 tls_secret_name: elasticsearch-es-cert
diff --git a/roles/smartgateway/tasks/main.yml b/roles/smartgateway/tasks/main.yml
index 7e504f5..80adabd 100644
--- a/roles/smartgateway/tasks/main.yml
+++ b/roles/smartgateway/tasks/main.yml
@@ -1,22 +1,23 @@
 ---
-- name: Write out configmap for smart gateway
-  template:
-    dest: /tmp/configmap.yaml
-    src: "{{ service_type }}-configmap.yaml.j2"
+# this will be useful later to understand if we're on vanilla k8s or OpenShift (OKD)
+- name: "Get information about the cluster"
+  set_fact:
+    api_groups: "{{ lookup('k8s', cluster_info='api_groups') }}"
 
-- name: Smart gateway ConfigMap
-  k8s:
-    src: /tmp/configmap.yaml
-
-- name: Create deployment for the Smart Gateway
-  template:
-    dest: /tmp/deployment.yaml
-    src: deployment.yaml.j2
+- name: "Set Smart Gateway container image"
+  set_fact:
+    container_image_path: "{{ lookup('env', 'SMARTGATEWAY_IMAGE') | default('quay.io/infrawatch/smart-gateway:latest', true) }}"
 
-- name: Deploy the Smart Gateway
+- name: Setup Smart Gateway
   k8s:
-    src: /tmp/deployment.yaml
-
-- name: Create service for the Smart Gateway
-  include_tasks: service.yml
-  when: service_type == "metrics"
+    state: "{{ state }}"
+    definition: "{{ lookup('template', item.name) | from_yaml }}"
+  when: item.to_load | default(True)
+  loop:
+    - name: events-configmap.yaml.j2
+      to_load: "{{ True if 'events' in service_type else False }}"
+    - name: metrics-configmap.yaml.j2
+      to_load: "{{ True if 'metrics' in service_type else False }}"
+    - name: deployment.yaml.j2
+    - name: service.yaml.j2
+      to_load: "{{ True if 'metrics' in service_type else False }}"
diff --git a/roles/smartgateway/tasks/service.yml b/roles/smartgateway/tasks/service.yml
deleted file mode 100644
index aa196f9..0000000
--- a/roles/smartgateway/tasks/service.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-- name: Service for the smart gateway
-  k8s:
-    resource_definition:
-      apiVersion: v1
-      kind: Service
-      metadata:
-        name: '{{ meta.name }}-smartgateway'
-        namespace: '{{ meta.namespace }}'
-        labels:
-          app: smart-gateway
-      spec:
-        ports:
-        - name: prom-http
-          port: 8081
-          targetPort: 8081
-          protocol: TCP
-        selector:
-          app: smart-gateway
-          deploymentconfig: '{{ meta.name }}-smartgateway'
\ No newline at end of file
diff --git a/roles/smartgateway/templates/deployment.yaml.j2 b/roles/smartgateway/templates/deployment.yaml.j2
index ed7a653..b19c0cb 100644
--- a/roles/smartgateway/templates/deployment.yaml.j2
+++ b/roles/smartgateway/templates/deployment.yaml.j2
@@ -1,14 +1,26 @@
-apiVersion: apps.openshift.io/v1
-kind: DeploymentConfig
+apiVersion: extensions/v1beta1
+kind: Deployment
 metadata:
   name: '{{ meta.name }}-smartgateway'
   namespace: '{{ meta.namespace }}'
 spec:
   replicas: {{ size }}
+  progressDeadlineSeconds: 600
+  revisionHistoryLimit: 10
+  strategy:
+    rollingUpdate:
+      maxSurge: 50%
+      maxUnavailable: 50%
+    type: RollingUpdate
+  selector:
+    matchLabels:
+      app: smart-gateway
+      smart-gateway: '{{ meta.name }}'
   template:
     metadata:
       labels:
         app: smart-gateway
+        smart-gateway: '{{ meta.name }}'
     spec:
       containers:
       - name: smart-gateway
diff --git a/roles/smartgateway/templates/service.yaml.j2 b/roles/smartgateway/templates/service.yaml.j2
new file mode 100644
index 0000000..ee02511
--- /dev/null
+++ b/roles/smartgateway/templates/service.yaml.j2
@@ -0,0 +1,17 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: '{{ meta.name }}-smartgateway'
+  namespace: '{{ meta.namespace }}'
+  labels:
+    app: smart-gateway
+    smart-gateway: '{{ meta.name }}'
+spec:
+  ports:
+  - name: prom-http
+    port: 8081
+    targetPort: 8081
+    protocol: TCP
+  selector:
+    app: smart-gateway
+    smart-gateway: '{{ meta.name }}'