From c4a4acafea27098dd161bd0d45c39fa1f58ed012 Mon Sep 17 00:00:00 2001
From: David Hoese <david.hoese@ssec.wisc.edu>
Date: Thu, 13 Aug 2020 16:53:07 -0500
Subject: [PATCH] Refactor CI and move main processing to geosphere namespace

---
 .gitlab-ci.yml                                | 254 ++----------------
 ci_gcp/gitlab-ci.yml                          |   1 +
 ci_geosphere-test/gitlab-ci.yml               | 150 +++++++++++
 .../values-tile-gen-g16-radc.yaml             |   5 +-
 .../values-tile-gen-g16-radf.yaml             |   5 +-
 .../values-tile-gen-g16-radm1.yaml            |  18 ++
 .../values-tile-gen-g16-radm2.yaml            |  18 ++
 .../geotiff-pvc.yaml                          |   0
 ci_geosphere/gitlab-ci.yml                    | 229 ++++++++++++++++
 ci_geosphere/shapefiles-pvc.yaml              |  12 +
 ci_geosphere/values-geo2grid-g16-radc.yaml    |  19 ++
 .../values-geo2grid-g16-radf.yaml             |   0
 ci_geosphere/values-geo2grid-g16-radm1.yaml   |  19 ++
 ci_geosphere/values-geo2grid-g16-radm2.yaml   |  19 ++
 ci_geosphere/values-geosphere-rabbit.yaml     |  12 +
 .../values-grb-g16.yaml                       |   0
 ci_geosphere/values-mapcache.yaml             |  37 +++
 ci_geosphere/values-mapserver.yaml            |  16 ++
 ci_geosphere/values-tile-gen-g16-radc.yaml    |  17 ++
 ci_geosphere/values-tile-gen-g16-radf.yaml    |  18 ++
 ci_geosphere/values-tile-gen-g16-radm1.yaml   |  17 ++
 ci_geosphere/values-tile-gen-g16-radm2.yaml   |  17 ++
 helpers/deploy_geo2grid.sh                    |  25 ++
 helpers/deploy_rabbitmq.sh                    |  33 +++
 helpers/deploy_tile_gen.sh                    |  10 +-
 helpers/get_chart.yaml                        |  28 ++
 helpers/get_namespace.sh                      |   5 +-
 27 files changed, 742 insertions(+), 242 deletions(-)
 create mode 100644 ci_gcp/gitlab-ci.yml
 create mode 100644 ci_geosphere-test/gitlab-ci.yml
 create mode 100644 ci_geosphere-test/values-tile-gen-g16-radm1.yaml
 create mode 100644 ci_geosphere-test/values-tile-gen-g16-radm2.yaml
 rename {ci_geosphere-test => ci_geosphere}/geotiff-pvc.yaml (100%)
 create mode 100644 ci_geosphere/gitlab-ci.yml
 create mode 100644 ci_geosphere/shapefiles-pvc.yaml
 create mode 100644 ci_geosphere/values-geo2grid-g16-radc.yaml
 rename {ci_geosphere-test => ci_geosphere}/values-geo2grid-g16-radf.yaml (100%)
 create mode 100644 ci_geosphere/values-geo2grid-g16-radm1.yaml
 create mode 100644 ci_geosphere/values-geo2grid-g16-radm2.yaml
 create mode 100644 ci_geosphere/values-geosphere-rabbit.yaml
 rename {ci_geosphere-test => ci_geosphere}/values-grb-g16.yaml (100%)
 create mode 100644 ci_geosphere/values-mapcache.yaml
 create mode 100644 ci_geosphere/values-mapserver.yaml
 create mode 100644 ci_geosphere/values-tile-gen-g16-radc.yaml
 create mode 100644 ci_geosphere/values-tile-gen-g16-radf.yaml
 create mode 100644 ci_geosphere/values-tile-gen-g16-radm1.yaml
 create mode 100644 ci_geosphere/values-tile-gen-g16-radm2.yaml
 create mode 100755 helpers/deploy_geo2grid.sh
 create mode 100755 helpers/deploy_rabbitmq.sh
 create mode 100644 helpers/get_chart.yaml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0cc0967..8cef1b7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -22,6 +22,10 @@ include:
   - local: "/helpers/build_image.yaml"
   - local: "/helpers/docker_base.yaml"
   - local: "/helpers/helm_base.yaml"
+  - local: "/helpers/get_chart.yaml"
+  - local: "/ci_geosphere/gitlab-ci.yaml"
+  - local: "/ci_geosphere-test/gitlab-ci.yaml"
+  - local: "/ci_gcp/gitlab-ci.yaml"
 
 
 build ci:
@@ -58,78 +62,6 @@ build sidecar rabbit init:
     - if: $BUILD_PREREQS
       when: always
 
-create geotiff storage:
-  extends: .helm_based_job
-  stage: create storage
-  script:
-    - ns=$(./helpers/get_namespace.sh)
-    # copy secret kubeconfig to the mounted (pwd) directory
-    - cp $kubekorner_k3s_config .
-    - kubeconfig=$(basename $kubekorner_k3s_config)
-    - ./helpers/create_pvc.sh "$ns" "ci_geosphere-test/geotiff-pvc.yaml" "cspp-geo-geo2grid" "$kubeconfig"
-  # this job doesn't actually need any artifacts from previous jobs
-  dependencies: []
-  rules:
-    - changes:
-        - ci_geosphere-test/geotiff-pvc.yaml
-      when: always
-    - if: $CREATE_STORAGE
-      when: always
-
-create shapefile storage:
-  extends: .helm_based_job
-  stage: create storage
-  script:
-    - ns=$(./helpers/get_namespace.sh)
-    # copy secret kubeconfig to the mounted (pwd) directory
-    - cp $kubekorner_k3s_config .
-    - kubeconfig=$(basename $kubekorner_k3s_config)
-    - ./helpers/create_pvc.sh "$ns" "ci_geosphere-test/shapefiles-pvc.yaml" "geosphere-tile-gen-shapefiles" "$kubeconfig"
-  # this job doesn't actually need any artifacts from previous jobs
-  dependencies: []
-  rules:
-    - changes:
-        - ci_geosphere-test/shapefiles-pvc.yaml
-      when: always
-    - if: $CREATE_STORAGE
-      when: always
-
-.get_chart_tmpl:
-  extends: .helm_based_job
-  stage: get chart
-  variables:
-    SUBCOMP_REPOS_BASE: "https://gitlab.ssec.wisc.edu/cspp_geo/geosphere"
-    # required:
-    SUBCOMP_REPOS: ""
-    SUBCOMP_CHART_DIR: ""
-    SUBCOMP_BRANCH: "master"
-  script:
-    - repos_url="${SUBCOMP_REPOS_BASE}/${SUBCOMP_REPOS}"
-    - git clone --depth 1 --branch ${SUBCOMP_BRANCH} $repos_url
-    - cd ${SUBCOMP_REPOS}
-    # most recent docker image should be tagged with most recent SHA
-    - docker_tag=$(git rev-parse --short=8 HEAD)
-    - echo $docker_tag
-    - cd chart
-    # make the docker tag available in later stages
-    - echo export docker_tag=$docker_tag >${SUBCOMP_CHART_DIR}/cibuild.env
-    - |-
-      sed -i "s/^appVersion: .*\$/appVersion: ${docker_tag}/g" ${SUBCOMP_CHART_DIR}/Chart.yaml
-    # debug:
-    - helm template ${SUBCOMP_CHART_DIR} ${SUBCOMP_CHART_DIR}
-  artifacts:
-    paths:
-      - ${SUBCOMP_REPOS}/chart/${SUBCOMP_CHART_DIR}
-    when: on_success
-    expire_in: 30 minutes
-# XXX: Do we always want to clone the subcomponent
-#  rules:
-#    - if: '$GEOSPHERE_SUBCOMP == ""'
-#      when: always
-#    - if: '$GEOSPHERE_SUBCOMP == $SUBCOMP_NAME'
-#      when: always
-#    - when: never
-
 get_chart_grb:
   extends: .get_chart_tmpl
   variables:
@@ -173,91 +105,17 @@ get_chart_client_test:
     SUBCOMP_CHART_DIR: "geosphere-client"
     SUBCOMP_BRANCH: "develop"
 
-deploy_prod_rabbit:
-  environment:
-    name: geosphere-test
-    url: http://geosphere-test.ssec.wisc.edu
-  extends: .helm_based_job
-  stage: deploy rabbit
-  script:
-    - ns=$(./helpers/get_namespace.sh)
-    # copy secret kubeconfig to the mounted (pwd) directory
-    - cp $kubekorner_k3s_config .
-    - kubeconfig=$(basename $kubekorner_k3s_config)
-    # get password from any previous installation
-    # if we don't do this the password will get out of sync
-    - sec_info=$(kubectl --kubeconfig $kubeconfig get secret --namespace geosphere-test geosphere-rabbit-rabbitmq || echo "")
-    - echo $sec_info
-    - auth_sec="geosphere-rabbit-rabbitmq"
-    - if [ "$sec_info" != "" ]; then
-        pw=$(kubectl --kubeconfig $kubeconfig get secret --namespace $ns $auth_sec -o jsonpath="{.data.rabbitmq-password}" | base64 -d);
-        ec=$(kubectl --kubeconfig $kubeconfig get secret --namespace $ns $auth_sec -o jsonpath="{.data.rabbitmq-erlang-cookie}" | base64 -d);
-        EXTRA_ARGS="--set auth.password=$pw --set auth.erlangCookie=$ec";
-      fi
-    - echo $EXTRA_ARGS
-    # install third-party rabbitmq server
-    - helm repo add bitnami "https://charts.bitnami.com/bitnami"
-    - helm upgrade -v 2 --install --kubeconfig $kubeconfig -f ci_geosphere-test/values-geosphere-rabbit.yaml $EXTRA_ARGS --namespace $ns geosphere-rabbit bitnami/rabbitmq
-    # do a little waiting for the rabbitmq pod to be ready so future stages
-    # don't fail to communicate with it
-    - kubectl wait -n geosphere-test pod/geosphere-rabbit-rabbitmq-0 --timeout 60s --for=condition=Ready
-  # this job doesn't actually need any artifacts from previous jobs
-  dependencies: []
-  rules:
-    - if: '$kubekorner_k3s_config == ""'
-      when: never
-    # no need to build if another project triggered us
-    - if: $CI_PIPELINE_SOURCE == "pipeline"
-      when: never
-    - changes:
-        - ci_geosphere-test/values-geosphere-rabbit.yaml
-      when: always
-    - if: $DEPLOY_RABBIT
-      when: always
-
-deploy_g16_grb:
-  environment:
-    name: geosphere-test
-    url: http://geosphere-test.ssec.wisc.edu
-  extends: .helm_based_job
-  stage: deploy GRB
-  script:
-    - ns=$(./helpers/get_namespace.sh)
-    - cd geosphere-grb/chart
-    - source cspp-geo-grb/cibuild.env
-    # copy secret kubeconfig to the mounted (pwd) directory
-    - cp $kubekorner_k3s_config .
-    - kubeconfig=$(basename $kubekorner_k3s_config)
-    - echo "Deploying version $docker_tag to cluster namespace $ns"
-    # copy extra values files to the local directory (where helm has access via docker mount)
-    - cp ../../ci_geosphere-test/values-grb-g16.yaml .
-    # namespace names are the same as domain names
-    - helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns --set persistence.enabled=true --set persistence.storageClass=longhorn -f values-grb-g16.yaml cspp-geo-grb cspp-geo-grb/
-  dependencies:
-    - get_chart_grb
-  rules:
-    - if: '$kubekorner_k3s_config == ""'
-      when: never
-    - when: on_success
-
-deploy_geo2grid_g16_radf:
-  environment:
-    name: geosphere-test
-    url: http://geosphere-test.ssec.wisc.edu
+.deploy_geo2grid:
+#  environment:
+#    name: geosphere-test
+#    url: http://geosphere-test.ssec.wisc.edu
+  variables:
+    DEPLOY_SUFFIX: ""
+    VALUES_DIR: ""
   extends: .helm_based_job
   stage: deploy G2G
   script:
-    - ns=$(./helpers/get_namespace.sh)
-    - cd geosphere-geo2grid/chart
-    - source cspp-geo-geo2grid/cibuild.env
-    # copy secret kubeconfig to the mounted (pwd) directory
-    - cp $kubekorner_k3s_config .
-    - kubeconfig=$(basename $kubekorner_k3s_config)
-    - echo "Deploying version $docker_tag to cluster namespace $ns"
-    # copy extra values files to the local directory (where helm has access via docker mount)
-    - cp ../../ci_geosphere-test/values-geo2grid-g16-radf.yaml .
-    # namespace names are the same as domain names
-    - helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns -f values-geo2grid-g16-radf.yaml cspp-geo-geo2grid cspp-geo-geo2grid/
+    - ./helpers/deploy_geo2grid.sh "${VALUES_DIR}" "${DEPLOY_SUFFIX}"
   dependencies:
     - get_chart_geo2grid
   rules:
@@ -271,10 +129,11 @@ deploy_geo2grid_g16_radf:
 #    url: http://geosphere-test.ssec.wisc.edu
   variables:
     DEPLOY_SUFFIX: ""
+    VALUES_DIR: ""
   extends: .helm_based_job
   stage: deploy tile gen
   script:
-    - ./helpers/deploy_tile_gen.sh "$DEPLOY_SUFFIX"
+    - ./helpers/deploy_tile_gen.sh "${VALUES_DIR}" "${DEPLOY_SUFFIX}"
   dependencies:
     - get_chart_tilegen
   rules:
@@ -282,30 +141,9 @@ deploy_geo2grid_g16_radf:
       when: never
     - when: on_success
 
-deploy tile gen g16 radf:
-  extends: .deploy_tile_gen
-  variables:
-    DEPLOY_SUFFIX: "-g16-radf"
-
-deploy tile gen g16 radc:
-  extends: .deploy_tile_gen
+.deploy_mapserver:
   variables:
-    DEPLOY_SUFFIX: "-g16-radc"
-
-#deploy_tile_gen_g16_radm1:
-#  extends: .deploy_tile_gen
-#  variables:
-#    DEPLOY_SUFFIX: "-g16-radm1"
-#
-#deploy_tile_gen_g16_radm2:
-#  extends: .deploy_tile_gen
-#  variables:
-#    DEPLOY_SUFFIX: "-g16-radm2"
-
-deploy_mapserver:
-  environment:
-    name: geosphere-test
-    url: http://geosphere-test.ssec.wisc.edu
+    VALUES_DIR: ""
   extends: .helm_based_job
   stage: deploy WMS
   script:
@@ -317,7 +155,7 @@ deploy_mapserver:
     - kubeconfig=$(basename $kubekorner_k3s_config)
     - echo "Deploying version $docker_tag to cluster namespace $ns"
     # copy extra values files to the local directory (where helm has access via docker mount)
-    - cp ../../ci_geosphere-test/values-mapserver.yaml .
+    - cp ../../${VALUES_DIR}/values-mapserver.yaml .
     # namespace names are the same as domain names
     - helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns -f values-mapserver.yaml geosphere-mapserver geosphere-mapserver/
   dependencies:
@@ -327,10 +165,9 @@ deploy_mapserver:
       when: never
     - when: on_success
 
-deploy_mapcache:
-  environment:
-    name: geosphere-test
-    url: http://geosphere-test.ssec.wisc.edu
+.deploy_mapcache:
+  variables:
+    VALUES_DIR: ""
   extends: .helm_based_job
   stage: deploy WMTS
   script:
@@ -342,7 +179,7 @@ deploy_mapcache:
     - kubeconfig=$(basename $kubekorner_k3s_config)
     - echo "Deploying version $docker_tag to cluster namespace $ns"
     # copy extra values files to the local directory (where helm has access via docker mount)
-    - cp ../../ci_geosphere-test/values-mapcache.yaml .
+    - cp ../../${VALUES_DIR}/values-mapcache.yaml .
     # namespace names are the same as domain names
     - helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns -f values-mapcache.yaml geosphere-mapcache geosphere-mapcache/
   dependencies:
@@ -352,52 +189,3 @@ deploy_mapcache:
       when: never
     - when: on_success
 
-deploy_client_test:
-  environment:
-    name: geosphere-test
-    url: http://geosphere-test.ssec.wisc.edu
-  extends: .helm_based_job
-  stage: deploy Client
-  script:
-    - ns="geosphere-test"
-    - cd geosphere-client/chart
-    - source geosphere-client/cibuild.env
-    # copy secret kubeconfig to the mounted (pwd) directory
-    - cp $kubekorner_k3s_config .
-    - kubeconfig=$(basename $kubekorner_k3s_config)
-    - echo "Deploying version $docker_tag to cluster namespace $ns"
-    # copy extra values files to the local directory (where helm has access via docker mount)
-    - cp ../../ci_geosphere-test/values-client.yaml .
-    # namespace names are the same as domain names
-    - helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns -f values-client.yaml geosphere-client geosphere-client/
-  dependencies:
-    - get_chart_client_test
-  rules:
-    - if: '$kubekorner_k3s_config == ""'
-      when: never
-    - when: on_success
-
-deploy_client_production:
-  environment:
-    name: geosphere
-    url: http://geosphere.ssec.wisc.edu
-  extends: .helm_based_job
-  stage: deploy Client
-  script:
-    - ns="geosphere"
-    - cd geosphere-client/chart
-    - source geosphere-client/cibuild.env
-    # copy secret kubeconfig to the mounted (pwd) directory
-    - cp $kubekorner_k3s_config .
-    - kubeconfig=$(basename $kubekorner_k3s_config)
-    - echo "Deploying version $docker_tag to cluster namespace $ns"
-    # copy extra values files to the local directory (where helm has access via docker mount)
-    - cp ../../ci_geosphere/values-client.yaml .
-    # namespace names are the same as domain names
-    - helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns -f values-client.yaml geosphere-client geosphere-client/
-  dependencies:
-    - get_chart_client
-  rules:
-    - if: '$kubekorner_k3s_config == ""'
-      when: never
-    - when: on_success
diff --git a/ci_gcp/gitlab-ci.yml b/ci_gcp/gitlab-ci.yml
new file mode 100644
index 0000000..3e5a6b5
--- /dev/null
+++ b/ci_gcp/gitlab-ci.yml
@@ -0,0 +1 @@
+# This file is included as part of the main repository .gitlab-ci.yml file
diff --git a/ci_geosphere-test/gitlab-ci.yml b/ci_geosphere-test/gitlab-ci.yml
new file mode 100644
index 0000000..006e186
--- /dev/null
+++ b/ci_geosphere-test/gitlab-ci.yml
@@ -0,0 +1,150 @@
+# This file is included as part of the main repository .gitlab-ci.yml file
+# NOTE: Since this is running from the root of the repository all referenced
+#       files must be relative to the root directory.
+# Most jobs in this file are only meant to be run from the master branch
+
+# geosphere-test currently uses GRB and geotiffs created from the main
+# geosphere site.
+
+# Prerequisites:
+#   Create TLS certificate secret:
+#     kubectl create -n geosphere-test secret tls geosphere-tls-certs --cert=geosphere_ssec_wisc_edu.crt --key=geosphere_ssec_wisc_edu.key
+
+gstest create shapefile storage:
+  extends: .helm_based_job
+  stage: create storage
+  script:
+    - ns=$(./helpers/get_namespace.sh)
+    # copy secret kubeconfig to the mounted (pwd) directory
+    - cp $kubekorner_k3s_config .
+    - kubeconfig=$(basename $kubekorner_k3s_config)
+    - ./helpers/create_pvc.sh "$ns" "ci_geosphere-test/shapefiles-pvc.yaml" "geosphere-tile-gen-shapefiles" "$kubeconfig"
+  # this job doesn't actually need any artifacts from previous jobs
+  dependencies: []
+  rules:
+    - if: "$CI_COMMIT_BRANCH == master"
+    - changes:
+        - ci_geosphere-test/shapefiles-pvc.yaml
+    - if: $CREATE_STORAGE
+
+gstest deploy rabbit:
+  environment:
+    name: geosphere-test
+    url: http://geosphere-test.ssec.wisc.edu
+  extends: .helm_based_job
+  stage: deploy rabbit
+  script:
+    - ./deploy_rabbitmq.sh ci_geosphere-test
+    - cp $kubekorner_k3s_config .
+    - kubeconfig=$(basename $kubekorner_k3s_config)
+    - |-
+      kubectl get secret geosphere-rabbit-rabbitmq --namespace=geosphere -oyaml | grep -v '^\s*namespace:\s' | grep -v "helm" | sed 's/ name: .*/ name: geosphere-rabbit-rabbitmq-production/' | kubectl apply --namespace=geosphere-test -f -
+  # this job doesn't actually need any artifacts from previous jobs
+  dependencies: []
+  rules:
+    - if: "$CI_COMMIT_BRANCH == master"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    # no need to build if another project triggered us
+    - if: $CI_PIPELINE_SOURCE == "pipeline"
+      when: never
+    - changes:
+        - ci_geosphere-test/values-geosphere-rabbit.yaml
+    - if: $DEPLOY_RABBIT
+
+gstest deploy tile gen g16 radf:
+  extends: .deploy_tile_gen
+  variables:
+    VALUES_DIR: "ci_geosphere-test"
+    DEPLOY_SUFFIX: "-g16-radf"
+  rules:
+    - if: "$CI_COMMIT_BRANCH == master"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gstest deploy tile gen g16 radc:
+  extends: .deploy_tile_gen
+  variables:
+    VALUES_DIR: "ci_geosphere-test"
+    DEPLOY_SUFFIX: "-g16-radc"
+  rules:
+    - if: "$CI_COMMIT_BRANCH == master"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gstest deploy tile gen g16 radm1:
+  extends: .deploy_tile_gen
+  variables:
+    VALUES_DIR: "ci_geosphere-test"
+    DEPLOY_SUFFIX: "-g16-radm1"
+  rules:
+    - if: "$CI_COMMIT_BRANCH == master"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gstest deploy tile gen g16 radm2:
+  extends: .deploy_tile_gen
+  variables:
+    VALUES_DIR: "ci_geosphere-test"
+    DEPLOY_SUFFIX: "-g16-radm2"
+  rules:
+    - if: "$CI_COMMIT_BRANCH == master"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gstest deploy mapserver:
+  environment:
+    name: geosphere-test
+    url: http://geosphere-test.ssec.wisc.edu
+  variables:
+    VALUES_DIR: "ci_geosphere-test"
+  extends: .deploy_mapserver
+  rules:
+    - if: "$CI_COMMIT_BRANCH == master"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gstest deploy mapcache:
+  environment:
+    name: geosphere-test
+    url: http://geosphere-test.ssec.wisc.edu
+  variables:
+    VALUES_DIR: "ci_geosphere-test"
+  extends: .deploy_mapcache
+  rules:
+    - if: "$CI_COMMIT_BRANCH == master"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gstest deploy client:
+  environment:
+    name: geosphere-test
+    url: http://geosphere-test.ssec.wisc.edu
+  extends: .helm_based_job
+  stage: deploy Client
+  script:
+    - ns="geosphere-test"
+    - cd geosphere-client/chart
+    - source geosphere-client/cibuild.env
+    # copy secret kubeconfig to the mounted (pwd) directory
+    - cp $kubekorner_k3s_config .
+    - kubeconfig=$(basename $kubekorner_k3s_config)
+    - echo "Deploying version $docker_tag to cluster namespace $ns"
+    # copy extra values files to the local directory (where helm has access via docker mount)
+    - cp ../../ci_geosphere-test/values-client.yaml .
+    # namespace names are the same as domain names
+    - helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns -f values-client.yaml geosphere-client geosphere-client/
+  dependencies:
+    - get_chart_client_test
+  rules:
+    - if: "$CI_COMMIT_BRANCH == master"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
diff --git a/ci_geosphere-test/values-tile-gen-g16-radc.yaml b/ci_geosphere-test/values-tile-gen-g16-radc.yaml
index f622126..7e9dc56 100644
--- a/ci_geosphere-test/values-tile-gen-g16-radc.yaml
+++ b/ci_geosphere-test/values-tile-gen-g16-radc.yaml
@@ -1,7 +1,8 @@
 rabbitIn:
-  host: "geosphere-rabbit-rabbitmq"
+  # use the rabbitmq from the production environment (geosphere)
+  host: "geosphere-rabbit-rabbitmq.geosphere"
   username: "user"
-  passwordSecret: "geosphere-rabbit-rabbitmq"
+  passwordSecret: "geosphere-rabbit-rabbitmq-production"
   topic: "data.goes.g16.abi.radc.l1b.geotiff.all.complete"
 rabbitOut:
   host: "geosphere-rabbit-rabbitmq"
diff --git a/ci_geosphere-test/values-tile-gen-g16-radf.yaml b/ci_geosphere-test/values-tile-gen-g16-radf.yaml
index 7438d4c..86975c2 100644
--- a/ci_geosphere-test/values-tile-gen-g16-radf.yaml
+++ b/ci_geosphere-test/values-tile-gen-g16-radf.yaml
@@ -1,7 +1,8 @@
 rabbitIn:
-  host: "geosphere-rabbit-rabbitmq"
+  # use the rabbitmq from the production environment (geosphere)
+  host: "geosphere-rabbit-rabbitmq.geosphere"
   username: "user"
-  passwordSecret: "geosphere-rabbit-rabbitmq"
+  passwordSecret: "geosphere-rabbit-rabbitmq-production"
   topic: "data.goes.g16.abi.radf.l1b.geotiff.all.complete"
 rabbitOut:
   host: "geosphere-rabbit-rabbitmq"
diff --git a/ci_geosphere-test/values-tile-gen-g16-radm1.yaml b/ci_geosphere-test/values-tile-gen-g16-radm1.yaml
new file mode 100644
index 0000000..f0aaa5b
--- /dev/null
+++ b/ci_geosphere-test/values-tile-gen-g16-radm1.yaml
@@ -0,0 +1,18 @@
+rabbitIn:
+  # use the rabbitmq from the production environment (geosphere)
+  host: "geosphere-rabbit-rabbitmq.geosphere"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq-production"
+  topic: "data.goes.g16.abi.radm1.l1b.geotiff.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+  existingClaim: "cspp-geo-geo2grid"
+destination:
+  #  s3Endpoint: "http://geosphere-minio:9000"
+  persistence:
+    enabled: true
+    storageClass: "longhorn"
+    existingClaim: "geosphere-tile-gen-shapefiles"
diff --git a/ci_geosphere-test/values-tile-gen-g16-radm2.yaml b/ci_geosphere-test/values-tile-gen-g16-radm2.yaml
new file mode 100644
index 0000000..c4548c4
--- /dev/null
+++ b/ci_geosphere-test/values-tile-gen-g16-radm2.yaml
@@ -0,0 +1,18 @@
+rabbitIn:
+  # use the rabbitmq from the production environment (geosphere)
+  host: "geosphere-rabbit-rabbitmq.geosphere"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq-production"
+  topic: "data.goes.g16.abi.radm2.l1b.geotiff.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+  existingClaim: "cspp-geo-geo2grid"
+destination:
+  #  s3Endpoint: "http://geosphere-minio:9000"
+  persistence:
+    enabled: true
+    storageClass: "longhorn"
+    existingClaim: "geosphere-tile-gen-shapefiles"
diff --git a/ci_geosphere-test/geotiff-pvc.yaml b/ci_geosphere/geotiff-pvc.yaml
similarity index 100%
rename from ci_geosphere-test/geotiff-pvc.yaml
rename to ci_geosphere/geotiff-pvc.yaml
diff --git a/ci_geosphere/gitlab-ci.yml b/ci_geosphere/gitlab-ci.yml
new file mode 100644
index 0000000..16d15e4
--- /dev/null
+++ b/ci_geosphere/gitlab-ci.yml
@@ -0,0 +1,229 @@
+# This file is included as part of the main repository .gitlab-ci.yml file
+# NOTE: Since this is running from the root of the repository all referenced
+#       files must be relative to the root directory.
+# Most jobs in this file are only meant to be run when a git tag is created
+
+# Prerequisites:
+#   Create TLS certificate secret:
+#     kubectl create -n geosphere secret tls geosphere-tls-certs --cert=geosphere_ssec_wisc_edu.crt --key=geosphere_ssec_wisc_edu.key
+
+gs create geotiff storage:
+  extends: .helm_based_job
+  stage: create storage
+  script:
+    - ns=$(./helpers/get_namespace.sh)
+    # copy secret kubeconfig to the mounted (pwd) directory
+    - cp $kubekorner_k3s_config .
+    - kubeconfig=$(basename $kubekorner_k3s_config)
+    - ./helpers/create_pvc.sh "$ns" "ci_geosphere/geotiff-pvc.yaml" "cspp-geo-geo2grid" "$kubeconfig"
+  # this job doesn't actually need any artifacts from previous jobs
+  dependencies: []
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - changes:
+        - ci_geosphere/geotiff-pvc.yaml
+    - if: $CREATE_STORAGE
+
+gs create shapefile storage:
+  extends: .helm_based_job
+  stage: create storage
+  script:
+    - ns=$(./helpers/get_namespace.sh)
+    # copy secret kubeconfig to the mounted (pwd) directory
+    - cp $kubekorner_k3s_config .
+    - kubeconfig=$(basename $kubekorner_k3s_config)
+    - ./helpers/create_pvc.sh "$ns" "ci_geosphere/shapefiles-pvc.yaml" "geosphere-tile-gen-shapefiles" "$kubeconfig"
+  # this job doesn't actually need any artifacts from previous jobs
+  dependencies: []
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - changes:
+        - ci_geosphere/shapefiles-pvc.yaml
+    - if: $CREATE_STORAGE
+
+gs deploy rabbit:
+  environment:
+    name: geosphere
+    url: http://geosphere.ssec.wisc.edu
+  extends: .helm_based_job
+  stage: deploy rabbit
+  script:
+    - ./deploy_rabbitmq.sh ci_geosphere
+  # this job doesn't actually need any artifacts from previous jobs
+  dependencies: []
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    # no need to build if another project triggered us
+    - if: $CI_PIPELINE_SOURCE == "pipeline"
+      when: never
+    - changes:
+        - ci_geosphere/values-geosphere-rabbit.yaml
+    - if: $DEPLOY_RABBIT
+
+gs deploy g16 grb:
+#  environment:
+#    name: geosphere
+#    url: http://geosphere.ssec.wisc.edu
+  extends: .helm_based_job
+  stage: deploy GRB
+  script:
+    - ns=$(./helpers/get_namespace.sh)
+    - cd geosphere-grb/chart
+    - source cspp-geo-grb/cibuild.env
+    # copy secret kubeconfig to the mounted (pwd) directory
+    - cp $kubekorner_k3s_config .
+    - kubeconfig=$(basename $kubekorner_k3s_config)
+    - echo "Deploying version $docker_tag to cluster namespace $ns"
+    # copy extra values files to the local directory (where helm has access via docker mount)
+    - cp ../../ci_geosphere/values-grb-g16.yaml .
+    # namespace names are the same as domain names
+    - helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns --set persistence.enabled=true --set persistence.storageClass=longhorn -f values-grb-g16.yaml cspp-geo-grb cspp-geo-grb/
+  dependencies:
+    - get_chart_grb
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy geo2grid g16 radf:
+  extends: .deploy_geo2grid
+  variables:
+    VALUES_DIR: "ci_geosphere"
+    DEPLOY_SUFFIX: "-g16-radf.yaml"
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy geo2grid g16 radc:
+  extends: .deploy_geo2grid
+  variables:
+    VALUES_DIR: "ci_geosphere"
+    DEPLOY_SUFFIX: "-g16-radc.yaml"
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy geo2grid g16 radm1:
+  extends: .deploy_geo2grid
+  variables:
+    VALUES_DIR: "ci_geosphere"
+    DEPLOY_SUFFIX: "-g16-radm1.yaml"
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy geo2grid g16 radm2:
+  extends: .deploy_geo2grid
+  variables:
+    VALUES_DIR: "ci_geosphere"
+    DEPLOY_SUFFIX: "-g16-radm2.yaml"
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy tile gen g16 radf:
+  extends: .deploy_tile_gen
+  variables:
+    VALUES_DIR: "ci_geosphere"
+    DEPLOY_SUFFIX: "-g16-radf"
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy tile gen g16 radc:
+  extends: .deploy_tile_gen
+  variables:
+    VALUES_DIR: "ci_geosphere"
+    DEPLOY_SUFFIX: "-g16-radc"
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy_tile_gen_g16_radm1:
+  extends: .deploy_tile_gen
+  variables:
+    VALUES_DIR: "ci_geosphere"
+    DEPLOY_SUFFIX: "-g16-radm1"
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy_tile_gen_g16_radm2:
+  extends: .deploy_tile_gen
+  variables:
+    VALUES_DIR: "ci_geosphere"
+    DEPLOY_SUFFIX: "-g16-radm2"
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy mapserver:
+  environment:
+    name: geosphere
+    url: http://geosphere.ssec.wisc.edu
+  variables:
+    VALUES_DIR: "ci_geosphere"
+  extends: .deploy_mapserver
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy mapcache:
+  environment:
+    name: geosphere
+    url: http://geosphere.ssec.wisc.edu
+  variables:
+    VALUES_DIR: "ci_geosphere"
+  extends: .deploy_mapcache
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+gs deploy client:
+  environment:
+    name: geosphere
+    url: http://geosphere.ssec.wisc.edu
+  extends: .helm_based_job
+  stage: deploy Client
+  script:
+    - ns="geosphere"
+    - cd geosphere-client/chart
+    - source geosphere-client/cibuild.env
+    # copy secret kubeconfig to the mounted (pwd) directory
+    - cp $kubekorner_k3s_config .
+    - kubeconfig=$(basename $kubekorner_k3s_config)
+    - echo "Deploying version $docker_tag to cluster namespace $ns"
+    # copy extra values files to the local directory (where helm has access via docker mount)
+    - cp ../../ci_geosphere/values-client.yaml .
+    # namespace names are the same as domain names
+    - helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns -f values-client.yaml geosphere-client geosphere-client/
+  dependencies:
+    - get_chart_client
+  rules:
+    - if: "$CI_COMMIT_TAG != null"
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
diff --git a/ci_geosphere/shapefiles-pvc.yaml b/ci_geosphere/shapefiles-pvc.yaml
new file mode 100644
index 0000000..d8a812c
--- /dev/null
+++ b/ci_geosphere/shapefiles-pvc.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: geosphere-tile-gen-shapefiles
+  labels: {}
+spec:
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 2Gi
+  storageClassName: "longhorn"
diff --git a/ci_geosphere/values-geo2grid-g16-radc.yaml b/ci_geosphere/values-geo2grid-g16-radc.yaml
new file mode 100644
index 0000000..1e1af9d
--- /dev/null
+++ b/ci_geosphere/values-geo2grid-g16-radc.yaml
@@ -0,0 +1,19 @@
+rabbitIn:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+  topic: "data.goes.g16.abi.radc.l1b.netcdf.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+#  s3Endpoint: "http://geosphere-minio:9000"
+  existingClaim: "cspp-geo-grb"
+destination:
+  persistence:
+    existingClaim: "cspp-geo-geo2grid"
+#  s3Endpoint: "http://geosphere-minio:9000"
+  s3Secret: "geosphere-minio"
+  s3AccessKey: "accesskey"
+  s3SecretKey: "secretkey"
diff --git a/ci_geosphere-test/values-geo2grid-g16-radf.yaml b/ci_geosphere/values-geo2grid-g16-radf.yaml
similarity index 100%
rename from ci_geosphere-test/values-geo2grid-g16-radf.yaml
rename to ci_geosphere/values-geo2grid-g16-radf.yaml
diff --git a/ci_geosphere/values-geo2grid-g16-radm1.yaml b/ci_geosphere/values-geo2grid-g16-radm1.yaml
new file mode 100644
index 0000000..42af277
--- /dev/null
+++ b/ci_geosphere/values-geo2grid-g16-radm1.yaml
@@ -0,0 +1,19 @@
+rabbitIn:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+  topic: "data.goes.g16.abi.radm1.l1b.netcdf.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+#  s3Endpoint: "http://geosphere-minio:9000"
+  existingClaim: "cspp-geo-grb"
+destination:
+  persistence:
+    existingClaim: "cspp-geo-geo2grid"
+#  s3Endpoint: "http://geosphere-minio:9000"
+  s3Secret: "geosphere-minio"
+  s3AccessKey: "accesskey"
+  s3SecretKey: "secretkey"
diff --git a/ci_geosphere/values-geo2grid-g16-radm2.yaml b/ci_geosphere/values-geo2grid-g16-radm2.yaml
new file mode 100644
index 0000000..8cef031
--- /dev/null
+++ b/ci_geosphere/values-geo2grid-g16-radm2.yaml
@@ -0,0 +1,19 @@
+rabbitIn:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+  topic: "data.goes.g16.abi.radm2.l1b.netcdf.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+#  s3Endpoint: "http://geosphere-minio:9000"
+  existingClaim: "cspp-geo-grb"
+destination:
+  persistence:
+    existingClaim: "cspp-geo-geo2grid"
+#  s3Endpoint: "http://geosphere-minio:9000"
+  s3Secret: "geosphere-minio"
+  s3AccessKey: "accesskey"
+  s3SecretKey: "secretkey"
diff --git a/ci_geosphere/values-geosphere-rabbit.yaml b/ci_geosphere/values-geosphere-rabbit.yaml
new file mode 100644
index 0000000..3fbe896
--- /dev/null
+++ b/ci_geosphere/values-geosphere-rabbit.yaml
@@ -0,0 +1,12 @@
+#rabbitmq:
+#  configuration: |-
+#    ## Clustering
+#    cluster_formation.peer_discovery_backend  = rabbit_peer_discovery_k8s
+#    cluster_formation.k8s.host = kubernetes.default.svc.cluster.local
+#    cluster_formation.node_cleanup.interval = 10
+#    cluster_formation.node_cleanup.only_log_warning = true
+#    cluster_partition_handling = autoheal
+#    # queue master locator
+#    queue_master_locator=min-masters
+#    # enable guest user
+#    loopback_users.guest = false
diff --git a/ci_geosphere-test/values-grb-g16.yaml b/ci_geosphere/values-grb-g16.yaml
similarity index 100%
rename from ci_geosphere-test/values-grb-g16.yaml
rename to ci_geosphere/values-grb-g16.yaml
diff --git a/ci_geosphere/values-mapcache.yaml b/ci_geosphere/values-mapcache.yaml
new file mode 100644
index 0000000..411c026
--- /dev/null
+++ b/ci_geosphere/values-mapcache.yaml
@@ -0,0 +1,37 @@
+rabbitIn:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+  topic: "data.goes.g16.abi.*.l1b.tiles.*.complete"
+wms:
+  host: "geosphere-mapserver"
+cache:
+  persistence:
+    enabled: true
+    storageClass: "local-path"
+seed:
+  images: true
+  overlays: true
+ingress:
+  enabled: true
+  annotations:
+    ingress.kubernetes.io/ssl-redirect: "true"
+  hosts:
+    - host: geosphere.ssec.wisc.edu
+      paths: ["/mapcache"]
+    - host: geosphere1.ssec.wisc.edu
+      paths: ["/mapcache"]
+    - host: geosphere2.ssec.wisc.edu
+      paths: ["/mapcache"]
+    - host: geosphere3.ssec.wisc.edu
+      paths: ["/mapcache"]
+    - host: geosphere4.ssec.wisc.edu
+      paths: ["/mapcache"]
+  tls:
+    - hosts:
+        - "geosphere.ssec.wisc.edu"
+        - "geosphere1.ssec.wisc.edu"
+        - "geosphere2.ssec.wisc.edu"
+        - "geosphere3.ssec.wisc.edu"
+        - "geosphere4.ssec.wisc.edu"
+      secretName: "geosphere-tls-certs"
diff --git a/ci_geosphere/values-mapserver.yaml b/ci_geosphere/values-mapserver.yaml
new file mode 100644
index 0000000..0b26288
--- /dev/null
+++ b/ci_geosphere/values-mapserver.yaml
@@ -0,0 +1,16 @@
+imageSource:
+  #  s3Endpoint: "http://geosphere-minio:9000"
+  existingClaim: "cspp-geo-geo2grid"
+tileSource:
+  existingClaim: "geosphere-tile-gen-shapefiles"
+ingress:
+  enabled: true
+  annotations:
+   ingress.kubernetes.io/ssl-redirect: "true"
+  hosts:
+    - host: geosphere.ssec.wisc.edu
+      paths: ["/wms", "/wms_times"]
+  tls:
+    - hosts:
+        - "geosphere.ssec.wisc.edu"
+      secretName: "geosphere-tls-certs"
diff --git a/ci_geosphere/values-tile-gen-g16-radc.yaml b/ci_geosphere/values-tile-gen-g16-radc.yaml
new file mode 100644
index 0000000..f622126
--- /dev/null
+++ b/ci_geosphere/values-tile-gen-g16-radc.yaml
@@ -0,0 +1,17 @@
+rabbitIn:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+  topic: "data.goes.g16.abi.radc.l1b.geotiff.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+  existingClaim: "cspp-geo-geo2grid"
+destination:
+  #  s3Endpoint: "http://geosphere-minio:9000"
+  persistence:
+    enabled: true
+    storageClass: "longhorn"
+    existingClaim: "geosphere-tile-gen-shapefiles"
diff --git a/ci_geosphere/values-tile-gen-g16-radf.yaml b/ci_geosphere/values-tile-gen-g16-radf.yaml
new file mode 100644
index 0000000..7438d4c
--- /dev/null
+++ b/ci_geosphere/values-tile-gen-g16-radf.yaml
@@ -0,0 +1,18 @@
+rabbitIn:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+  topic: "data.goes.g16.abi.radf.l1b.geotiff.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+  existingClaim: "cspp-geo-geo2grid"
+destination:
+  #  s3Endpoint: "http://geosphere-minio:9000"
+  persistence:
+    enabled: true
+    storageClass: "longhorn"
+    existingClaim: "geosphere-tile-gen-shapefiles"
+
diff --git a/ci_geosphere/values-tile-gen-g16-radm1.yaml b/ci_geosphere/values-tile-gen-g16-radm1.yaml
new file mode 100644
index 0000000..98c4408
--- /dev/null
+++ b/ci_geosphere/values-tile-gen-g16-radm1.yaml
@@ -0,0 +1,17 @@
+rabbitIn:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+  topic: "data.goes.g16.abi.radm1.l1b.geotiff.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+  existingClaim: "cspp-geo-geo2grid"
+destination:
+  #  s3Endpoint: "http://geosphere-minio:9000"
+  persistence:
+    enabled: true
+    storageClass: "longhorn"
+    existingClaim: "geosphere-tile-gen-shapefiles"
diff --git a/ci_geosphere/values-tile-gen-g16-radm2.yaml b/ci_geosphere/values-tile-gen-g16-radm2.yaml
new file mode 100644
index 0000000..b9c8c46
--- /dev/null
+++ b/ci_geosphere/values-tile-gen-g16-radm2.yaml
@@ -0,0 +1,17 @@
+rabbitIn:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+  topic: "data.goes.g16.abi.radm2.l1b.geotiff.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+  existingClaim: "cspp-geo-geo2grid"
+destination:
+  #  s3Endpoint: "http://geosphere-minio:9000"
+  persistence:
+    enabled: true
+    storageClass: "longhorn"
+    existingClaim: "geosphere-tile-gen-shapefiles"
diff --git a/helpers/deploy_geo2grid.sh b/helpers/deploy_geo2grid.sh
new file mode 100755
index 0000000..b7bb0d3
--- /dev/null
+++ b/helpers/deploy_geo2grid.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+set -e
+
+if [ $# -ne 2 ]; then
+    echo "Usage: ./helpers/deploy_geo2grid.sh <values_base_dir> <deploy_suffix>"
+    exit 1
+fi
+
+# ci_geosphere-test
+values_base="$1"
+# Example: -g16-radf
+deploy_suffix="$2"
+
+ns=$(./helpers/get_namespace.sh)
+cd geosphere-tile-gen/chart
+source geosphere-tile-gen/cibuild.env
+# copy secret kubeconfig to the mounted (pwd) directory
+cp $kubekorner_k3s_config .
+kubeconfig=$(basename $kubekorner_k3s_config)
+echo "Deploying version $docker_tag to cluster namespace $ns"
+# copy extra values files to the local directory (where helm has access via docker mount)
+cp ../../${values_base}/values-geo2grid${deploy_suffix}.yaml .
+# namespace names are the same as domain names
+helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns -f values-geo2grid${deploy_suffix}.yaml cspp-geo-geo2grid${deploy_suffix} cspp-geo-geo2grid/
diff --git a/helpers/deploy_rabbitmq.sh b/helpers/deploy_rabbitmq.sh
new file mode 100755
index 0000000..6e796bb
--- /dev/null
+++ b/helpers/deploy_rabbitmq.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+set -e
+
+if [ $# -ne 1 ]; then
+    echo "Usage: ./helpers/deploy_rabbitmq.sh <values_base_dir>"
+    exit 1
+fi
+
+# ci_geosphere-test
+values_base="$1"
+
+ns=$(./helpers/get_namespace.sh)
+# copy secret kubeconfig to the mounted (pwd) directory
+cp $kubekorner_k3s_config .
+kubeconfig=$(basename $kubekorner_k3s_config)
+# get password from any previous installation
+# if we don't do this the password will get out of sync
+sec_info=$(kubectl --kubeconfig $kubeconfig get secret --namespace geosphere-test geosphere-rabbit-rabbitmq || echo "")
+echo $sec_info
+auth_sec="geosphere-rabbit-rabbitmq"
+if [[ "$sec_info" != "" ]]; then
+    pw=$(kubectl --kubeconfig $kubeconfig get secret --namespace $ns $auth_sec -o jsonpath="{.data.rabbitmq-password}" | base64 -d);
+    ec=$(kubectl --kubeconfig $kubeconfig get secret --namespace $ns $auth_sec -o jsonpath="{.data.rabbitmq-erlang-cookie}" | base64 -d);
+    EXTRA_ARGS="--set auth.password=$pw --set auth.erlangCookie=$ec";
+fi
+echo $EXTRA_ARGS
+# install third-party rabbitmq server
+helm repo add bitnami "https://charts.bitnami.com/bitnami"
+helm upgrade -v 2 --install --kubeconfig $kubeconfig -f ${values_base}/values-geosphere-rabbit.yaml $EXTRA_ARGS --namespace $ns geosphere-rabbit bitnami/rabbitmq
+# do a little waiting for the rabbitmq pod to be ready so future stages
+# don't fail to communicate with it
+kubectl wait -n $ns pod/geosphere-rabbit-rabbitmq-0 --timeout 60s --for=condition=Ready
diff --git a/helpers/deploy_tile_gen.sh b/helpers/deploy_tile_gen.sh
index 7389520..554e4ab 100755
--- a/helpers/deploy_tile_gen.sh
+++ b/helpers/deploy_tile_gen.sh
@@ -2,13 +2,15 @@
 
 set -e
 
-if [ $# -ne 1 ]; then
-    echo "Usage: ./helpers/deploy_tile_gen.sh <deploy_suffix>"
+if [ $# -ne 2 ]; then
+    echo "Usage: ./helpers/deploy_tile_gen.sh <values_base_dir> <deploy_suffix>"
     exit 1
 fi
 
+# ci_geosphere-test
+values_base="$1"
 # Example: -g16-radf
-deploy_suffix="$1"
+deploy_suffix="$2"
 
 ns=$(./helpers/get_namespace.sh)
 cd geosphere-tile-gen/chart
@@ -18,6 +20,6 @@ cp $kubekorner_k3s_config .
 kubeconfig=$(basename $kubekorner_k3s_config)
 echo "Deploying version $docker_tag to cluster namespace $ns"
 # copy extra values files to the local directory (where helm has access via docker mount)
-cp ../../ci_geosphere-test/values-tile-gen${deploy_suffix}.yaml .
+cp ../../${values_base}/values-tile-gen${deploy_suffix}.yaml .
 # namespace names are the same as domain names
 helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns -f values-tile-gen${deploy_suffix}.yaml geosphere-tile-gen${deploy_suffix} geosphere-tile-gen/
diff --git a/helpers/get_chart.yaml b/helpers/get_chart.yaml
new file mode 100644
index 0000000..dfbd515
--- /dev/null
+++ b/helpers/get_chart.yaml
@@ -0,0 +1,28 @@
+.get_chart_tmpl:
+  extends: .helm_based_job
+  stage: get chart
+  variables:
+    SUBCOMP_REPOS_BASE: "https://gitlab.ssec.wisc.edu/cspp_geo/geosphere"
+    # required:
+    SUBCOMP_REPOS: ""
+    SUBCOMP_CHART_DIR: ""
+    SUBCOMP_BRANCH: "master"
+  script:
+    - repos_url="${SUBCOMP_REPOS_BASE}/${SUBCOMP_REPOS}"
+    - git clone --depth 1 --branch ${SUBCOMP_BRANCH} $repos_url
+    - cd ${SUBCOMP_REPOS}
+    # most recent docker image should be tagged with most recent SHA
+    - docker_tag=$(git rev-parse --short=8 HEAD)
+    - echo $docker_tag
+    - cd chart
+    # make the docker tag available in later stages
+    - echo export docker_tag=$docker_tag >${SUBCOMP_CHART_DIR}/cibuild.env
+    - |-
+      sed -i "s/^appVersion: .*\$/appVersion: ${docker_tag}/g" ${SUBCOMP_CHART_DIR}/Chart.yaml
+    # debug:
+    - helm template ${SUBCOMP_CHART_DIR} ${SUBCOMP_CHART_DIR}
+  artifacts:
+    paths:
+      - ${SUBCOMP_REPOS}/chart/${SUBCOMP_CHART_DIR}
+    when: on_success
+    expire_in: 30 minutes
diff --git a/helpers/get_namespace.sh b/helpers/get_namespace.sh
index 450c2a8..b897775 100755
--- a/helpers/get_namespace.sh
+++ b/helpers/get_namespace.sh
@@ -2,8 +2,11 @@
 
 if [[ -n "$CI_COMMIT_TAG" ]]; then
     ns="geosphere";
-else
+elif [[ "$CI_COMMIT_BRANCH" == "master" ]]; then
     ns="geosphere-test";
+else
+    echo "ERROR: Kubernetes jobs don't run unless in master branch or tagged"
+    exit 1
 fi
 
 echo $ns
-- 
GitLab