diff --git a/Jenkinsfile b/Jenkinsfile index 2e59c2e318..93e32d7151 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -69,6 +69,7 @@ node { sh script: "make k3d/clean K3S_VERSION=${kubernetes_version['k3s']} KUBECTL_VERSION=${kubernetes_version['kubectl']}", label: "Removing any previous k3d versions" sh script: "make k3d K3S_VERSION=${kubernetes_version['k3s']} KUBECTL_VERSION=${kubernetes_version['kubectl']}", label: "Making k3d" sh script: "make -O${SYNC_MAKE_OUTPUT} k8s-tests -j2", label: "Making kubernetes tests" + sh script: "make -O${SYNC_MAKE_OUTPUT} controller-k8s-tests -j2", label: "Making controller based kubernetes tests" } catch (e) { echo "Something went wrong, trying to cleanup" cleanup() diff --git a/Makefile b/Makefile index 1b6aea9df1..a0c1160662 100644 --- a/Makefile +++ b/Makefile @@ -401,6 +401,29 @@ build/yarn-workspace-builder: build/node__10-builder images/yarn-workspace-build $(call docker_build,$(image),images/$(image)/Dockerfile,.) touch $@ +####### +####### Task Images +####### +####### Task Images are standalone images that are used to run advanced tasks when using the builddeploy controllers. + +# task-activestandby is the task image that lagoon builddeploy controller uses to run active/standby misc tasks +build/task-activestandby: taskimages/activestandby/Dockerfile + +# the `taskimages` are the name of the task directories contained within `taskimages/` in the repostory root +taskimages := activestandby +# in the following process, taskimages are prepended with `task-` to make built task images more identifiable +# use `build/task-` to build it, but the references in the directory structure remain simpler with +# taskimages/ +# activestandby +# anothertask +# the resulting image will be called `task-` instead of `` to make it known that it is a task image +task-images += $(foreach image,$(taskimages),task-$(image)) +build-taskimages = $(foreach image,$(taskimages),build/task-$(image)) +$(build-taskimages): + $(eval image = $(subst build/task-,,$@)) + $(call docker_build,task-$(image),taskimages/$(image)/Dockerfile,taskimages/$(image)) + touch $@ + # Variables of service images we manage and build services := api \ auth-server \ @@ -421,6 +444,7 @@ services := api \ kubernetesjobsmonitor \ kubernetesmisc \ kubernetesremove \ + controllerhandler \ webhook-handler \ webhooks2tasks \ backup-handler \ @@ -463,7 +487,7 @@ $(build-services): touch $@ # Dependencies of Service Images -build/auth-server build/logs2email build/logs2slack build/logs2rocketchat build/logs2microsoftteams build/openshiftbuilddeploy build/openshiftbuilddeploymonitor build/openshiftjobs build/openshiftjobsmonitor build/openshiftmisc build/openshiftremove build/backup-handler build/kubernetesbuilddeploy build/kubernetesdeployqueue build/kubernetesbuilddeploymonitor build/kubernetesjobs build/kubernetesjobsmonitor build/kubernetesmisc build/kubernetesremove build/webhook-handler build/webhooks2tasks build/api build/ui: build/yarn-workspace-builder +build/auth-server build/logs2email build/logs2slack build/logs2rocketchat build/logs2microsoftteams build/openshiftbuilddeploy build/openshiftbuilddeploymonitor build/openshiftjobs build/openshiftjobsmonitor build/openshiftmisc build/openshiftremove build/backup-handler build/kubernetesbuilddeploy build/kubernetesdeployqueue build/kubernetesbuilddeploymonitor build/kubernetesjobs build/kubernetesjobsmonitor build/kubernetesmisc build/kubernetesremove build/controllerhandler build/webhook-handler build/webhooks2tasks build/api build/ui: build/yarn-workspace-builder build/logs2logs-db: build/logstash__7 build/logs-db: build/elasticsearch__7 build/logs-db-ui: build/kibana__7 @@ -482,6 +506,7 @@ build/harborregistryctl: build/harborregistry build/harbor-nginx: build/harborregistryctl services/harbor-core/Dockerfile services/harbor-portal/Dockerfile build/tests: build/python__2.7 build/tests-kubernetes: build/tests +build/tests-controller-kubernetes: build/tests build/tests-openshift: build/tests build/toolbox: build/mariadb build/api-redis: build/redis @@ -523,7 +548,7 @@ s3-images += $(service-images) # Builds all Images .PHONY: build -build: $(foreach image,$(base-images) $(base-images-with-versions) $(service-images),build/$(image)) +build: $(foreach image,$(base-images) $(base-images-with-versions) $(service-images) $(task-images),build/$(image)) # Outputs a list of all Images we manage .PHONY: build-list build-list: @@ -553,8 +578,30 @@ $(all-k8s-tests): k3d kubernetes-test-services-up "$$(cat $$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)') | \ jq -rcsR '{kubeconfig: .}')" +# Define list of all tests +all-controller-k8s-tests-list:= features-kubernetes \ + nginx \ + drupal \ + active-standby-kubernetes +all-controller-k8s-tests = $(foreach image,$(all-controller-k8s-tests-list),controller-k8s-tests/$(image)) + +# Run all k8s tests +.PHONY: controller-k8s-tests +controller-k8s-tests: $(all-controller-k8s-tests) + +.PHONY: $(all-controller-k8s-tests) +$(all-controller-k8s-tests): k3d controller-k8s-test-services-up + $(MAKE) push-local-registry -j6 + $(eval testname = $(subst controller-k8s-tests/,,$@)) + IMAGE_REPO=$(CI_BUILD_TAG) docker-compose -p $(CI_BUILD_TAG) --compatibility run --rm \ + tests-controller-kubernetes ansible-playbook --skip-tags="skip-on-kubernetes" \ + /ansible/tests/$(testname).yaml \ + --extra-vars \ + "$$(cat $$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)') | \ + jq -rcsR '{kubeconfig: .}')" + # push command of our base images into minishift -push-local-registry-images = $(foreach image,$(base-images) $(base-images-with-versions),[push-local-registry]-$(image)) +push-local-registry-images = $(foreach image,$(base-images) $(base-images-with-versions) $(task-images),[push-local-registry]-$(image)) # tag and push all images .PHONY: push-local-registry push-local-registry: $(push-local-registry-images) @@ -590,7 +637,7 @@ openshift-tests: $(all-openshift-tests) # Run all tests .PHONY: tests -tests: k8s-tests openshift-tests +tests: controller-k8s-tests k8s-tests openshift-tests # Wait for Keycloak to be ready (before this no API calls will work) .PHONY: wait-for-keycloak @@ -607,6 +654,9 @@ openshift-test-services = openshiftremove openshiftbuilddeploy openshiftbuilddep # Define a list of which Lagoon Services are needed for kubernetes testing kubernetes-test-services = kubernetesbuilddeploy kubernetesdeployqueue kubernetesbuilddeploymonitor kubernetesjobs kubernetesjobsmonitor kubernetesremove kubernetesmisc tests-kubernetes local-registry local-dbaas-provider drush-alias +# Define a list of which Lagoon Services are needed for controller kubernetes testing +controller-k8s-test-services = controllerhandler tests-controller-kubernetes local-registry local-dbaas-provider drush-alias + # List of Lagoon Services needed for webhook endpoint testing webhooks-test-services = webhook-handler webhooks2tasks backup-handler @@ -637,6 +687,10 @@ openshift-test-services-up: main-test-services-up $(foreach image,$(openshift-te kubernetes-test-services-up: main-test-services-up $(foreach image,$(kubernetes-test-services),build/$(image)) IMAGE_REPO=$(CI_BUILD_TAG) docker-compose -p $(CI_BUILD_TAG) --compatibility up -d $(kubernetes-test-services) +.PHONY: controller-k8s-test-services-up +controller-k8s-test-services-up: main-test-services-up $(foreach image,$(controller-k8s-test-services),build/$(image)) + IMAGE_REPO=$(CI_BUILD_TAG) docker-compose -p $(CI_BUILD_TAG) --compatibility up -d $(controller-k8s-test-services) + .PHONY: drupaltest-services-up drupaltest-services-up: main-test-services-up $(foreach image,$(drupal-test-services),build/$(image)) IMAGE_REPO=$(CI_BUILD_TAG) docker-compose -p $(CI_BUILD_TAG) --compatibility up -d $(drupal-test-services) @@ -649,6 +703,12 @@ webhooks-test-services-up: main-test-services-up $(foreach image,$(webhooks-test local-registry-up: build/local-registry IMAGE_REPO=$(CI_BUILD_TAG) docker-compose -p $(CI_BUILD_TAG) --compatibility up -d local-registry +# broker-up is used to ensure the broker is running before the lagoon-builddeploy operator is installed +# when running controller-kubernetes tests +.PHONY: broker-up +broker-up: build/broker + IMAGE_REPO=$(CI_BUILD_TAG) docker-compose -p $(CI_BUILD_TAG) --compatibility up -d broker + openshift-run-api-tests = $(foreach image,$(api-tests),openshift-tests/$(image)) .PHONY: $(openshift-run-api-tests) $(openshift-run-api-tests): minishift build/oc-build-deploy-dind openshift-test-services-up push-minishift @@ -1015,6 +1075,7 @@ endif k3d: local-dev/k3d local-dev/kubectl local-dev/helm/helm build/docker-host $(MAKE) local-registry-up + $(MAKE) broker-up $(info starting k3d with name $(K3D_NAME)) $(info Creating Loopback Interface for docker gateway if it does not exist, this might ask for sudo) ifeq ($(ARCH), darwin) @@ -1044,6 +1105,13 @@ endif local-dev/helm/helm --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --kube-context='$(K3D_NAME)' repo add dbaas-operator https://raw.githubusercontent.com/amazeeio/dbaas-operator/master/charts ; \ local-dev/helm/helm --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --kube-context='$(K3D_NAME)' upgrade --install -n dbaas-operator dbaas-operator dbaas-operator/dbaas-operator ; \ local-dev/helm/helm --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --kube-context='$(K3D_NAME)' upgrade --install -n dbaas-operator mariadbprovider dbaas-operator/mariadbprovider -f local-dev/helm-values-mariadbprovider.yml ; \ + local-dev/kubectl --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --context='$(K3D_NAME)' create namespace lagoon-builddeploy; \ + local-dev/helm/helm --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --kube-context='$(K3D_NAME)' repo add lagoon-builddeploy https://raw.githubusercontent.com/amazeeio/lagoon-kbd/main/charts ; \ + local-dev/helm/helm --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --kube-context='$(K3D_NAME)' upgrade --install -n lagoon-builddeploy lagoon-builddeploy lagoon-builddeploy/lagoon-builddeploy \ + --set vars.lagoonTargetName=ci-local-control-k8s \ + --set vars.rabbitPassword=guest \ + --set vars.rabbitUsername=guest \ + --set vars.rabbitHostname=172.17.0.1:5672; \ local-dev/kubectl --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --context='$(K3D_NAME)' create namespace lagoon; \ local-dev/helm/helm --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --kube-context='$(K3D_NAME)' repo add amazeeio https://amazeeio.github.io/charts/; \ local-dev/helm/helm --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --kube-context='$(K3D_NAME)' upgrade --install -n lagoon lagoon-remote amazeeio/lagoon-remote --set dockerHost.image.name=172.17.0.1:5000/lagoon/docker-host --set dockerHost.registry=172.17.0.1:5000; \ @@ -1052,14 +1120,20 @@ ifeq ($(ARCH), darwin) export KUBECONFIG="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')"; \ KUBERNETESBUILDDEPLOY_TOKEN=$$(local-dev/kubectl --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --context='$(K3D_NAME)' -n lagoon describe secret $$(local-dev/kubectl --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --context='$(K3D_NAME)' -n lagoon get secret | grep kubernetesbuilddeploy | awk '{print $$1}') | grep token: | awk '{print $$2}'); \ sed -i '' -e "s/\".*\" # make-kubernetes-token/\"$${KUBERNETESBUILDDEPLOY_TOKEN}\" # make-kubernetes-token/g" local-dev/api-data/03-populate-api-data-kubernetes.gql; \ + sed -i '' -e "s/\".*\" # make-kubernetes-token/\"$${KUBERNETESBUILDDEPLOY_TOKEN}\" # make-kubernetes-token/g" local-dev/api-data/04-populate-api-data-controller.gql; \ DOCKER_IP="$$(docker network inspect bridge --format='{{(index .IPAM.Config 0).Gateway}}')"; \ - sed -i '' -e "s/172\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/$${DOCKER_IP}/g" local-dev/api-data/03-populate-api-data-kubernetes.gql docker-compose.yaml; + sed -i '' -e "s/172\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/$${DOCKER_IP}/g" local-dev/api-data/03-populate-api-data-kubernetes.gql docker-compose.yaml; \ + DOCKER_IP="$$(docker network inspect bridge --format='{{(index .IPAM.Config 0).Gateway}}')"; \ + sed -i '' -e "s/172\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/$${DOCKER_IP}/g" local-dev/api-data/04-populate-api-data-controller.gql docker-compose.yaml; else export KUBECONFIG="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')"; \ KUBERNETESBUILDDEPLOY_TOKEN=$$(local-dev/kubectl --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --context='$(K3D_NAME)' -n lagoon describe secret $$(local-dev/kubectl --kubeconfig="$$(./local-dev/k3d get-kubeconfig --name='$(K3D_NAME)')" --context='$(K3D_NAME)' -n lagoon get secret | grep kubernetesbuilddeploy | awk '{print $$1}') | grep token: | awk '{print $$2}'); \ sed -i "s/\".*\" # make-kubernetes-token/\"$${KUBERNETESBUILDDEPLOY_TOKEN}\" # make-kubernetes-token/g" local-dev/api-data/03-populate-api-data-kubernetes.gql; \ + sed -i "s/\".*\" # make-kubernetes-token/\"$${KUBERNETESBUILDDEPLOY_TOKEN}\" # make-kubernetes-token/g" local-dev/api-data/04-populate-api-data-controller.gql; \ + DOCKER_IP="$$(docker network inspect bridge --format='{{(index .IPAM.Config 0).Gateway}}')"; \ + sed -i "s/172\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/$${DOCKER_IP}/g" local-dev/api-data/03-populate-api-data-kubernetes.gql docker-compose.yaml; \ DOCKER_IP="$$(docker network inspect bridge --format='{{(index .IPAM.Config 0).Gateway}}')"; \ - sed -i "s/172\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/$${DOCKER_IP}/g" local-dev/api-data/03-populate-api-data-kubernetes.gql docker-compose.yaml; + sed -i "s/172\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/$${DOCKER_IP}/g" local-dev/api-data/04-populate-api-data-controller.gql docker-compose.yaml; endif $(MAKE) push-kubectl-build-deploy-dind diff --git a/docker-compose.yaml b/docker-compose.yaml index d0194bc09b..e00cc3b6cf 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -198,6 +198,16 @@ services: lagoon.type: custom lagoon.template: services/kubernetesremove/.lagoon.app.yml lagoon.image: amazeeiolagoon/kubernetesremove:v1-8-2 + controllerhandler: + image: ${IMAGE_REPO:-lagoon}/controllerhandler + command: yarn run dev + volumes: + - ./services/controllerhandler/src:/app/services/controllerhandler/src + - ./node-packages:/app/node-packages:delegated + labels: + lagoon.type: custom + lagoon.template: services/controllerhandler/.lagoon.app.yml + lagoon.image: amazeeiolagoon/controllerhandler:v1-8-2 logs2rocketchat: image: ${IMAGE_REPO:-lagoon}/logs2rocketchat command: yarn run dev @@ -262,6 +272,9 @@ services: volumes: - ./services/api/src:/app/services/api/src - ./node-packages:/app/node-packages:delegated + environment: + - CI=${CI:-true} + - REGISTRY=172.17.0.1:8084 # Docker network bridge and forwarded port for harbor-nginx depends_on: - api-db - keycloak @@ -350,9 +363,34 @@ services: - WEBHOOK_HOST=webhook-handler - WEBHOOK_PORT=3000 - WEBHOOK_PROTOCOL=http - - ROUTE_SUFFIX_HTTP=172.17.0.1.xip.io + - ROUTE_SUFFIX_HTTP=172.17.0.1.nip.io + - ROUTE_SUFFIX_HTTP_PORT=18080 + - ROUTE_SUFFIX_HTTPS=172.17.0.1.nip.io + - ROUTE_SUFFIX_HTTPS_PORT=18443 + - WEBHOOK_REPO_PREFIX=ssh://git@172.17.0.1:2222/git/ + - GIT_REPO_PREFIX=git@local-git:/git/ + - SSH_PRIVATE_KEY=-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY----- + - SSH_HOST=ssh + - SSH_PORT=2020 + - API_HOST=api + - API_PROTOCOL=http + - API_PORT=3000 + - KEYCLOAK_AUTH_SERVER_CLIENT_SECRET=f605b150-7636-4447-abd3-70988786b330 + - DELETED_STATUS_CODE=404 + volumes: + - ./tests:/ansible + labels: + lagoon.type: none + tests-controller-kubernetes: + image: ${IMAGE_REPO:-lagoon}/tests + environment: + - CLUSTER_TYPE=control-k8s + - WEBHOOK_HOST=webhook-handler + - WEBHOOK_PORT=3000 + - WEBHOOK_PROTOCOL=http + - ROUTE_SUFFIX_HTTP=172.17.0.1.nip.io - ROUTE_SUFFIX_HTTP_PORT=18080 - - ROUTE_SUFFIX_HTTPS=172.17.0.1.xip.io + - ROUTE_SUFFIX_HTTPS=172.17.0.1.nip.io - ROUTE_SUFFIX_HTTPS_PORT=18443 - WEBHOOK_REPO_PREFIX=ssh://git@172.17.0.1:2222/git/ - GIT_REPO_PREFIX=git@local-git:/git/ @@ -375,9 +413,9 @@ services: - WEBHOOK_HOST=webhook-handler - WEBHOOK_PORT=3000 - WEBHOOK_PROTOCOL=http - - ROUTE_SUFFIX_HTTP=192.168.42.103.xip.io + - ROUTE_SUFFIX_HTTP=192.168.42.103.nip.io - ROUTE_SUFFIX_HTTP_PORT=80 - - ROUTE_SUFFIX_HTTPS=192.168.42.103.xip.io + - ROUTE_SUFFIX_HTTPS=192.168.42.103.nip.io - ROUTE_SUFFIX_HTTPS_PORT=443 - WEBHOOK_REPO_PREFIX=ssh://git@172.17.0.1:2222/git/ - GIT_REPO_PREFIX=git@local-git:/git/ diff --git a/docs/administering_lagoon/rbac.md b/docs/administering_lagoon/rbac.md index 055818477e..7141d4ae04 100644 --- a/docs/administering_lagoon/rbac.md +++ b/docs/administering_lagoon/rbac.md @@ -159,6 +159,7 @@ Here is a table that lists the roles and the access they have: | getFilesByTaskId | task | view | projectID | Yes | Yes | Yes | Yes | Yes | Yes | Yes | | | getTasksByEnvironmentId | task | view | projectID | Yes | Yes | Yes | Yes | Yes | Yes | Yes | | | getTaskByRemoteId | task | view | projectID | Yes | Yes | Yes | Yes | Yes | Yes | Yes | | +| getTaskById | task | view | projectID | Yes | Yes | Yes | Yes | Yes | Yes | Yes | | | addUser | user | add | | Yes | Yes | Yes | Yes | Yes | Yes | Yes | | | updateUser | user | update | userId | Yes | Yes | | | | | | Yes | | deleteUser | user | delete | userId | Yes | Yes | | | | | | Yes | diff --git a/docs/using_lagoon/active_standby.md b/docs/using_lagoon/active_standby.md index e31567308c..9856e41f7c 100644 --- a/docs/using_lagoon/active_standby.md +++ b/docs/using_lagoon/active_standby.md @@ -71,17 +71,16 @@ mutation ActiveStandby { } ){ id - remoteId } } ``` A task is created in the current active environment `tasks` tab when a switch event is triggered, you can check the status of the switch here. -Using the `remoteId` from the `switchActiveStandby` mutation, we can also check the status of the task. +Using the `id` from the `switchActiveStandby` mutation, we can also check the status of the task. ``` query getTask { - taskByRemoteId(id: "") { + taskById(id: ) { id name created diff --git a/images/yarn-workspace-builder/Dockerfile b/images/yarn-workspace-builder/Dockerfile index 9dc991492e..bcfa7b31a8 100644 --- a/images/yarn-workspace-builder/Dockerfile +++ b/images/yarn-workspace-builder/Dockerfile @@ -30,6 +30,7 @@ COPY services/openshiftjobs/package.json /app/services/openshiftjobs/ COPY services/openshiftjobsmonitor/package.json /app/services/openshiftjobsmonitor/ COPY services/openshiftmisc/package.json /app/services/openshiftmisc/ COPY services/openshiftremove/package.json /app/services/openshiftremove/ +COPY services/controllerhandler/package.json /app/services/controllerhandler/ COPY services/webhook-handler/package.json /app/services/webhook-handler/ COPY services/webhooks2tasks/package.json /app/services/webhooks2tasks/ COPY services/ui/package.json /app/services/ui/ diff --git a/local-dev/api-data-watcher-pusher/api-watch-push.sh b/local-dev/api-data-watcher-pusher/api-watch-push.sh index f4d4f054f5..27832e66ff 100755 --- a/local-dev/api-data-watcher-pusher/api-watch-push.sh +++ b/local-dev/api-data-watcher-pusher/api-watch-push.sh @@ -4,6 +4,7 @@ clear_gql_file_path="/api-data/00-clear-api-data.gql" populate_general_gql_file_path="/api-data/01-populate-api-data-general.gql" populate_openshift_gql_file_path="/api-data/02-populate-api-data-openshift.gql" populate_kubernetes_gql_file_path="/api-data/03-populate-api-data-kubernetes.gql" +populate_controller_gql_file_path="/api-data/04-populate-api-data-controller.gql" send_graphql_query() { local file_path=${1} @@ -26,6 +27,7 @@ watch_apidatafolder() { chsum_populate_general_prev="" chsum_populate_openshift_prev="" chsum_populate_kubernetes_prev="" + chsum_populate_controller_prev="" while [[ true ]] do @@ -33,12 +35,14 @@ watch_apidatafolder() { chsum_populate_general_curr=`md5sum $populate_general_gql_file_path` chsum_populate_openshift_curr=`md5sum $populate_openshift_gql_file_path` chsum_populate_kubernetes_curr=`md5sum $populate_kubernetes_gql_file_path` + chsum_populate_controller_curr=`md5sum $populate_controller_gql_file_path` if [[ $chsum_clear_prev != $chsum_clear_curr ]] || [[ $chsum_populate_general_prev != $chsum_populate_general_curr ]] || [[ $chsum_populate_openshift_prev != $chsum_populate_openshift_curr ]] || - [[ $chsum_populate_kubernetes_prev != $chsum_populate_kubernetes_curr ]]; + [[ $chsum_populate_kubernetes_prev != $chsum_populate_kubernetes_curr ]] || + [[ $chsum_populate_controller_prev != $chsum_populate_controller_curr ]]; then echo "******* Found changes in gql files in /api-data/, clearing and re-populating" @@ -74,6 +78,13 @@ watch_apidatafolder() { echo "**** ERROR while re-populating $populate_kubernetes_gql_file_path, will try again." fi + if + send_graphql_query $populate_controller_gql_file_path; + then + chsum_populate_controller_prev=$chsum_populate_controller_curr + else + echo "**** ERROR while re-populating $populate_controller_gql_file_path, will try again." + fi fi diff --git a/local-dev/api-data/02-populate-api-data-openshift.gql b/local-dev/api-data/02-populate-api-data-openshift.gql index 9fc9d20581..91022b18bd 100644 --- a/local-dev/api-data/02-populate-api-data-openshift.gql +++ b/local-dev/api-data/02-populate-api-data-openshift.gql @@ -6,7 +6,7 @@ mutation PopulateApi { id: 2 name: "ci-local-openshift" consoleUrl: "https://192.168.42.103:8443/" - routerPattern: "${project}.${branch}.192.168.42.103.xip.io" + routerPattern: "${project}.${branch}.192.168.42.103.nip.io" projectUser: "developer" sshHost: "172.17.0.1" sshPort: "2020" @@ -885,7 +885,7 @@ mutation PopulateApi { CiActiveStandby: addProject( input: { id: 24 - name: "ci-active-standby" + name: "ci-active-standby-openshift" openshift: 2 gitUrl: "ssh://git@172.17.0.1:2222/git/active-standby.git" productionEnvironment:"master-a" @@ -898,7 +898,7 @@ mutation PopulateApi { CiActiveStandbyGroup3: addGroupsToProject( input: { project: { - name: "ci-active-standby" + name: "ci-active-standby-openshift" } groups: [ { @@ -911,7 +911,7 @@ mutation PopulateApi { } CiActiveStandbyRocketChat: addNotificationToProject( input: { - project: "ci-active-standby" + project: "ci-active-standby-openshift" notificationType: ROCKETCHAT notificationName: "amazeeio--lagoon-local-ci" } @@ -920,7 +920,7 @@ mutation PopulateApi { } CiActiveStandbyEmail: addNotificationToProject( input: { - project: "ci-active-standby" + project: "ci-active-standby-openshift" notificationType: EMAIL notificationName: "local-email-testing" } diff --git a/local-dev/api-data/03-populate-api-data-kubernetes.gql b/local-dev/api-data/03-populate-api-data-kubernetes.gql index 7d1c58da82..58c8b3add7 100644 --- a/local-dev/api-data/03-populate-api-data-kubernetes.gql +++ b/local-dev/api-data/03-populate-api-data-kubernetes.gql @@ -6,10 +6,10 @@ mutation PopulateApi { id: 1002 name: "ci-local-kubernetes" consoleUrl: "https://172.17.0.1:16643/" # make-host-docker-internal - routerPattern: "${project}.${environment}.172.17.0.1.xip.io" + routerPattern: "${project}.${environment}.172.17.0.1.nip.io" sshHost: "172.17.0.1" sshPort: "2020" - token: "eyJhbGciOiJSUzI1NiIsImtpZCI6ImNMaTF3aC1PR2dSeElnMlJXdG5kOUF5d1N1X1JQVGZhQUo0WHBYcEVMUUEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJsYWdvb24iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoia3ViZXJuZXRlc2J1aWxkZGVwbG95LXRva2VuLWY1OGQ1Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imt1YmVybmV0ZXNidWlsZGRlcGxveSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImEyN2NiOTBhLTQ0MDAtNDljYy04Yzc1LWQ4NTAyZmRmMDhhNCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpsYWdvb246a3ViZXJuZXRlc2J1aWxkZGVwbG95In0.dvmjV1_XXt__2juq392y2M1LyfFUGZz6D3do5ywkLy7zXz1IUv5Qf9dPAk4t3NP4xjtbhR_jJc8pWnVSP1Z2d1tZqj-XYJJvAf6YHXv8L4ram-MObz0x0zyCVK8w_bbzwWCEySM92eUI_TtpPCxFyEhJE7XJ--NppzBq-LaQ8eb8WvOrR5YHJAej1_HrtyQ_4Lm2DAm8dug-ptuAYQ8X4CWbXq-L_dmQnt-LgnKCCbDnvxo8XIJ_LQeMewtwtWmwOXscwGGM2Gq3C-9ykrnI1hd42GE_otLRBHTKLZfJ34eIYXsxXoMIXllxZp4O-NSIzEtafoaOL6BOQkSitAADZQ" # make-kubernetes-token + token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IklNQzJBVTk1NUd5d2VTSlJuVDNzWTNnaFQ2dEZFSDBaeWZBeWxuaTllQ1UifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJsYWdvb24iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoia3ViZXJuZXRlc2J1aWxkZGVwbG95LXRva2VuLWpmN25sIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imt1YmVybmV0ZXNidWlsZGRlcGxveSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjUwYTg1MjdmLTNmODItNGFiMy05ZTU3LTg5NGFiM2Y5ZDc4ZiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpsYWdvb246a3ViZXJuZXRlc2J1aWxkZGVwbG95In0.KQ6qyBotyv_ZuZYEbqZ1gp-60uUWYamGG076Vx3wsytPIADEtGxAx9k2gjrfGDjplSJjWlpvjKAJghphXFybgMG4SSCcxqkxft0mZbj1Md0FJq-bY-AZ7j0sNngHyaPqfodx_9sbjtYN46paQ9oRs9SuPuVGI3jVZvAWLi1gBXmlGu-Le8rpbucE_45Psoc5lkIqQz9f8S9EBS3s_52pThmdR2O-YqmrF_Go2NVQAPM1NFyAAOiamsLIsfzH6_Q1ugEA04SMx5fgEuLFVdchNT-RL5X3ACHmMpFbY1FFkdhm_FL_rJaJpwzb6ci6H8YPCpwBnsdznbqnJNhRwnW0jg" # make-kubernetes-token } ) { id @@ -1123,7 +1123,7 @@ mutation PopulateApi { CiActiveStandby: addProject( input: { id: 1024 - name: "ci-active-standby-k8s" + name: "ci-active-standby-kubernetes" openshift: 1002 gitUrl: "ssh://git@172.17.0.1:2222/git/active-standby.git" productionEnvironment:"master-a" @@ -1140,7 +1140,7 @@ mutation PopulateApi { CiActiveStandbyGroup3: addGroupsToProject( input: { project: { - name: "ci-active-standby-k8s" + name: "ci-active-standby-kubernetes" } groups: [ { @@ -1153,7 +1153,7 @@ mutation PopulateApi { } CiActiveStandbyRocketChat: addNotificationToProject( input: { - project: "ci-active-standby-k8s" + project: "ci-active-standby-kubernetes" notificationType: ROCKETCHAT notificationName: "amazeeio--lagoon-local-ci" } @@ -1162,7 +1162,7 @@ mutation PopulateApi { } CiActiveStandbyEmail: addNotificationToProject( input: { - project: "ci-active-standby-k8s" + project: "ci-active-standby-kubernetes" notificationType: EMAIL notificationName: "local-email-testing" } diff --git a/local-dev/api-data/04-populate-api-data-controller.gql b/local-dev/api-data/04-populate-api-data-controller.gql new file mode 100644 index 0000000000..3afe5750f0 --- /dev/null +++ b/local-dev/api-data/04-populate-api-data-controller.gql @@ -0,0 +1,1173 @@ +mutation PopulateApi { + #### Populate API with needed Objects to run the Credentialstests + + CiLocalKubernetes: addOpenshift( + input: { + id: 2001 + name: "ci-local-control-k8s" + consoleUrl: "https://172.17.0.1:16643/" # make-host-docker-internal + routerPattern: "${project}.${environment}.172.17.0.1.nip.io" + sshHost: "172.17.0.1" + sshPort: "2020" + token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjZWamZLTzEzZ2lPSGFtc0d6QXVkWXpDYi1fcmlfLWVBd3JtbEEydGItTHcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJsYWdvb24iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoia3ViZXJuZXRlc2J1aWxkZGVwbG95LXRva2VuLXJxNDg1Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imt1YmVybmV0ZXNidWlsZGRlcGxveSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjA3YzViODAxLTI5ZDgtNDU5Ni1hODBlLTZlMmU3MmY3YmMwMCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpsYWdvb246a3ViZXJuZXRlc2J1aWxkZGVwbG95In0.srj-zZguNXCQbeTIS5GtJw7Jl61k_miC8hXED70NQULm6OAMkImHrURRCfD4kjKPy-jbwEI88m5TNLFP8_0sMfdwj2vr2Gv8fTC55qoAJ589ff_dwv8THSKdKNj6VaHynzEzQ4IfZscd3ogP4HYF9alt-X4mMcJ2BApBt4F13Hg-bE2-4uzO0b_u13pJhzn0XrH8JGXWP0_oMPtE7M0zJL9BfOrBph_MgSb2djSbVBNbhPJ0fs9-eIB5aAu0NmqPhpxj6WL4UOAKX178IsDAq4vtRZrScZwvZxRcaDUxZ-MgwewWI8Ll0yg7UCxtZTdkLglkCgpjTK33Ei0PXWdE4A" # make-kubernetes-token + } + ) { + id + } + + ### Projects + CredentialstestProject1: addProject( + input: { + id: 2001 + name: "credentialstest-project1-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/project1.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + } + ) { + id + } + CredentialstestProject1Group1: addGroupsToProject( + input: { + project: { + name: "credentialstest-project1-control-k8s" + } + groups: [ + { + name: "credentialtest-group1" + } + ] + } + ) { + id + } + CredentialstestProject2: addProject( + input: { + id: 2002 + name: "credentialstest-project2-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/project2.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + } + ) { + id + } + CredentialstestProject2Group2: addGroupsToProject( + input: { + project: { + name: "credentialstest-project2-control-k8s" + } + groups: [ + { + name: "credentialtest-group2" + } + ] + } + ) { + id + } + CredentialstestProject3: addProject( + input: { + id: 2022 + name: "credentialstest-project3-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/project2.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + } + ) { + id + } + CredentialstestProject3Group3: addGroupsToProject( + input: { + project: { + name: "credentialstest-project3-control-k8s" + } + groups: [ + { + name: "credentialtest-group3" + } + ] + } + ) { + id + } + + # Projects for CI + CiGithub1: addProject( + input: { + id: 2003 + name: "ci-github-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/github.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiGithub1Group3: addGroupsToProject( + input: { + project: { + name: "ci-github-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiGithubRocketChat: addNotificationToProject( + input: { + project: "ci-github-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiGithubEmail: addNotificationToProject( + input: { + project: "ci-github-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + CiGithubEnvironment: addOrUpdateEnvironment( + input: { + id: 2001 + name: "master" + project: 2003 + deployType: BRANCH + deployBaseRef: "master" + environmentType: PRODUCTION + openshiftProjectName: "ci-local-control-k8s" + } + ) { + id + } + + CiGitlab: addProject( + input: { + id: 2004 + name: "ci-gitlab-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/gitlab.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiGitlabGroup3: addGroupsToProject( + input: { + project: { + name: "ci-gitlab-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiGitlabRocketChat: addNotificationToProject( + input: { + project: "ci-gitlab-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiGitlabEmail: addNotificationToProject( + input: { + project: "ci-gitlab-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiBitbucket: addProject( + input: { + id: 2005 + name: "ci-bitbucket-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/bitbucket.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIJKAIBAAKCAgEAxGZZrOV7Islo5p51Moabfd1YB8qbHvQZfJDZJmSU4jNxMf8G\nQH8KIM6ndi60xIiDlkh9R50Gs0fgnPaBwpjMjcUay5EvzBJdMmd/EPhg359+4f5Z\nQiGTVaB5UoGJKg9DEK4Xxi+QLpQ1CiJXvd3QOqnQlJZ2WYwz4kdLxF0d+sRrl+0G\nAISt9Gg9kq6wa7k7RRr4/OyD/9DhDr1GXvHXFPRv6QqKq084CqiUaarP7OcbZKi5\nEyMkf0s86ZTttQPqQijWsenLAw6t7J0vM38eojPDMFX4fJ7wVvbHmsdcwb2YxwD0\nk7I85mV5uM99v7owJ/0YSJGcN2YESq8c68rbRp1iSfDhchd9SUyYMFlrj3R+dxte\nTwvN2W5hIEld8Ip+dUWUVaaTeLkFLmqmVhvcMJNmuj+Wnp9USwki6U5HdpgBJPT5\nYJia3/LyE5IlPaRfZ+vBDQqKOeeqkncVtqcZ468ylT0qpqjtV4OSuCzl+P/TeJ+K\npCxDoqp88yQpYRYn9ztvEVvOkT8RERnT0/NVCNKAwHFOXrkK/BJs/h3fj2NddeVC\nJXdwiB4m+T2C/RHtGxVColqUf2nEntXxweuJgqBz+4YxXqRrKu4p5L4NuudcFAyg\nbIRpbaTZDI+vmmXnTXNP6ymMo5fNJ0/IPEBAoDkkc6ZmKdM5Yth6RaCzolsCAwEA\nAQKCAgBRL4n0SaxcFevyISCLMU+HeP8RwXPcGMWMU4ggMcXFt8QcCbK46Ir0QtjA\nps/8yf2zGuYGu2dwps63s8KyAV3VYNwRuEOM1S6HTncdOb850YGuw+h7yMtRwxND\nwt5Db6mmdIDJYRH13zgJp2ajytRv25CoS4ZCwA0WhahRVLi214kudUFc53vNI2YI\ng4PUE+7nQx4X12E9V0ghQqabStdBB0ZXjA8Ef6vH5CXthDmNUX9mXcSbn5RPtndI\ni1Kz2Bl3HdCaHO3ZprDItbU0UWEFZeZSzcb5JO5u1HZwiebTA5/q638uqqg4CUyG\n0+bEYZ/Ud/AY13A/CkHN6ZNH+UQotCH3GLyaTQq6OhyXlgMBojn3xs9iMUclFcuy\nkbZ1jAxqci25pxCIeNDHBDKRyxgSkDPna8ZZ4eKGXjIZzsds4+IDkYJLMg0OCtd2\nKm+ZPM2CFU2YCqt11dlr0higGK/9gdpajJMVgEYAmigQ670LdcBc4XIOpPMrR70a\nPjbF9ze/UqtKDWtz8KMIUcvr0CjhHa3XRgMJiM34hIOZU6xf6rjEgkN2Geq24u1b\nhUW8URb+5dcasQ9iIfkNn3R+zK5PzyvQNf6+XrbVjpLqPHXJYrD85EKlXkPqiE6y\n3ehYMrIaZIY6gMuIVcg8AEtsm5EwQY7ETw4YnMQLKfyweLsHEQKCAQEA5vavDyQj\nn6PqfF1Ntr3N/FfwRr/167HB+/3wHT+FwRpCw62ACeBC0iFXmzG2wfQfot60fUGa\nQEJiUDGZFvBM0tiTpzmgGG7QpRbPe1919Sl5LZeLA9bngRnmqn5zAkmVTeBCO/4F\nMSk9hnBZ0v0W3DqNmjuIH298g3gl4VJeKpILd62LbhjvhjT/LXlekYDEj3p9Xob8\n1OQxFJgftFyg4P07RRaUzsNLhqEdY3VxDcUMb9459fEYeb7sYig+zVPaZQ31aMVK\nj6K+XiH5M5uKJWkPdMDUG84jreFAdBY9kGCuSulTWgmTLlMKSI85q5hkckY2EQQL\n5u456xfyuFcnEwKCAQEA2bCCcqcGIAiMwk/6z7XIJeUsSUg+ObvkEdogk5n6Y1Ea\nt5LxMpQzhG6SHJ2f38VyKgv9e/jnwXI8eiejper6OeQEBG4+AedcLYi0V5SUMIgD\nX4bxT9+qCwYrwt9YHkJySk237WZUWJPVfxHg0vqNYyD/CXBowx0nm8jEuZ8iT+CW\nO2uZq+0DO2WqoYT54lZux6aEzm+oAkzwJJVXJcUVPg7bJXK1ObOzvHpkZJxHL8+S\nKufzew/CXALKWHoCkEP/P8b7oxjcjQI3KK0EM2fABNvN28+qscqTqQjfAsNw24Ob\nP8rL8amgd/x7iddIbEpOSoLAH1gVoxJXA0oqkC6YmQKCAQEAiIeoomW1nUgTdCLf\nrrfyzUnaoqgVIpf42RKa319OnQD+GJg2iSAFwBuvovE3XN4H2YqW3Thri7LyVP+M\nxM+WSkl2tzLMXcUcF4staXvbyeoTVQ0xQzrFrT53aa/IIsEGvntkC/y0awQ6937w\nylWMLvF6BYNNi2+nBjx+//xl5/pfRwbS1mltJkOr2ODXM2IQT9STyc44JU0jak4m\n58Kd44IuiD+6BaPSwKn7KnEhPIeQO4z9bFJyKn3fVIL/5Pa9smEXAjEmS1Rj/ldM\n7eHzPvwlA9p9SFaKJt5x8G25ROCyB1x4RlBEreyutofcCoDSV+8DRPnEY2XN3RhS\nBgCW+wKCAQAyHrqaDSyS2YUXA/UaN59CYlZk9PYmssTa+16+vRfyH+1H0NQpsgd+\neTq4ze3ORpZ3adVN4svxNQ0JjvDVtZkxFPd70aoDJDKL5UqoU3QfDGHCb75FhpiO\n+ze+IVAXf3Ly+pvbU9Edp8PjAsnBqaA9743orXHhYmgJLRtmJWZv/6R3P9ncxLAW\nz9yOXaBu5TmSTBuNsBV9mhs8QQoUjyDJ7f+0yolBJMfAIGnW5EhbkK31pPvhHIrC\nRn4yCr1mW9F77KNpNMMq0BTFD7jE4SFLvRPThSem0Z5Xr8wwxbDJSa7H7DgyhryE\ng6Qp42AwVpdZ/mqfjNdGeWWBQ2UzVxcZAoIBAHNXgjD3umcKciYRAbltNJrXx9xk\ndAv8I69oEMCy4hCmvKUjy/UI9NqXFjBb/G6VGgh6NUE9o9o27t1Y5Plm0izyCA1M\nDFruaRfjyJ8qjbEifcqRtcF3rzsBiXIwdmbN6qT4PUipN2elpUAd7J1OIwGIIe3u\nCWNyOTNL+2+oQ/Eg1Y99mg3yrsVyOwhynVE80/X5cy07bXXR5rv1x4NKSVbPhlnt\nL6J5iAoqoDKICzjcgF5x3mj9YFWZrC3aRxRrN5RoEgeVdcXeK56UJqXHjmKN++m3\nc8OPEIBZiD8UJuhSNSOLiBFrGz6toy6rpHavqqknGhVWotXsAs1h8LNkBe8=\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiBitbucketGroup3: addGroupsToProject( + input: { + project: { + name: "ci-bitbucket-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiBitbucketRocketChat: addNotificationToProject( + input: { + project: "ci-bitbucket-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiBitbucketEmail: addNotificationToProject( + input: { + project: "ci-bitbucket-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + + CiRest: addProject( + input: { + id: 2006 + name: "ci-rest-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/rest.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiRestGroup3: addGroupsToProject( + input: { + project: { + name: "ci-rest-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiRestRocketChat: addNotificationToProject( + input: { + project: "ci-rest-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiRestEmail: addNotificationToProject( + input: { + project: "ci-rest-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiNode: addProject( + input: { + id: 2007 + name: "ci-node-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/node.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiNodeGroup3: addGroupsToProject( + input: { + project: { + name: "ci-node-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiNodeRocketChat: addNotificationToProject( + input: { + project: "ci-node-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiNodeEmail: addNotificationToProject( + input: { + project: "ci-node-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiMultiproject1: addProject( + input: { + id: 2008 + name: "ci-multiproject1-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/multiproject.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiMultiproject1Group3: addGroupsToProject( + input: { + project: { + name: "ci-multiproject1-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiMultiproject1RocketChat: addNotificationToProject( + input: { + project: "ci-multiproject1-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiMultiproject1Email: addNotificationToProject( + input: { + project: "ci-multiproject1-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiMultiproject2: addProject( + input: { + id: 2009 + name: "ci-multiproject2-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/multiproject.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiMultiproject2Group3: addGroupsToProject( + input: { + project: { + name: "ci-multiproject2-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiMultiproject2RocketChat: addNotificationToProject( + input: { + project: "ci-multiproject2-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiMultiproject2Email: addNotificationToProject( + input: { + project: "ci-multiproject2-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiDrupal: addProject( + input: { + id: 2010 + name: "ci-drupal-control-k8s" + openshift: 2001 + developmentEnvironmentsLimit: 10 + gitUrl: "ssh://git@172.17.0.1:2222/git/drupal.git" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + productionEnvironment:"master" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiDrupalGroup3: addGroupsToProject( + input: { + project: { + name: "ci-drupal-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiDrupalRocketChat: addNotificationToProject( + input: { + project: "ci-drupal-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + + CiDrupalEmail: addNotificationToProject( + input: { + project: "ci-drupal-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiNginx: addProject( + input: { + id: 2011 + name: "ci-nginx-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/nginx.git" + productionEnvironment:"master" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + } + ) { + id + } + CiNginxGroup3: addGroupsToProject( + input: { + project: { + name: "ci-nginx-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiNginxRocketChat: addNotificationToProject( + input: { + project: "ci-nginx-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiNginxEmail: addNotificationToProject( + input: { + project: "ci-nginx-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiFeatures: addProject( + input: { + id: 2012 + name: "ci-features-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/features.git" + productionEnvironment: "master" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIJKAIBAAKCAgEAxGZZrOV7Islo5p51Moabfd1YB8qbHvQZfJDZJmSU4jNxMf8G\nQH8KIM6ndi60xIiDlkh9R50Gs0fgnPaBwpjMjcUay5EvzBJdMmd/EPhg359+4f5Z\nQiGTVaB5UoGJKg9DEK4Xxi+QLpQ1CiJXvd3QOqnQlJZ2WYwz4kdLxF0d+sRrl+0G\nAISt9Gg9kq6wa7k7RRr4/OyD/9DhDr1GXvHXFPRv6QqKq084CqiUaarP7OcbZKi5\nEyMkf0s86ZTttQPqQijWsenLAw6t7J0vM38eojPDMFX4fJ7wVvbHmsdcwb2YxwD0\nk7I85mV5uM99v7owJ/0YSJGcN2YESq8c68rbRp1iSfDhchd9SUyYMFlrj3R+dxte\nTwvN2W5hIEld8Ip+dUWUVaaTeLkFLmqmVhvcMJNmuj+Wnp9USwki6U5HdpgBJPT5\nYJia3/LyE5IlPaRfZ+vBDQqKOeeqkncVtqcZ468ylT0qpqjtV4OSuCzl+P/TeJ+K\npCxDoqp88yQpYRYn9ztvEVvOkT8RERnT0/NVCNKAwHFOXrkK/BJs/h3fj2NddeVC\nJXdwiB4m+T2C/RHtGxVColqUf2nEntXxweuJgqBz+4YxXqRrKu4p5L4NuudcFAyg\nbIRpbaTZDI+vmmXnTXNP6ymMo5fNJ0/IPEBAoDkkc6ZmKdM5Yth6RaCzolsCAwEA\nAQKCAgBRL4n0SaxcFevyISCLMU+HeP8RwXPcGMWMU4ggMcXFt8QcCbK46Ir0QtjA\nps/8yf2zGuYGu2dwps63s8KyAV3VYNwRuEOM1S6HTncdOb850YGuw+h7yMtRwxND\nwt5Db6mmdIDJYRH13zgJp2ajytRv25CoS4ZCwA0WhahRVLi214kudUFc53vNI2YI\ng4PUE+7nQx4X12E9V0ghQqabStdBB0ZXjA8Ef6vH5CXthDmNUX9mXcSbn5RPtndI\ni1Kz2Bl3HdCaHO3ZprDItbU0UWEFZeZSzcb5JO5u1HZwiebTA5/q638uqqg4CUyG\n0+bEYZ/Ud/AY13A/CkHN6ZNH+UQotCH3GLyaTQq6OhyXlgMBojn3xs9iMUclFcuy\nkbZ1jAxqci25pxCIeNDHBDKRyxgSkDPna8ZZ4eKGXjIZzsds4+IDkYJLMg0OCtd2\nKm+ZPM2CFU2YCqt11dlr0higGK/9gdpajJMVgEYAmigQ670LdcBc4XIOpPMrR70a\nPjbF9ze/UqtKDWtz8KMIUcvr0CjhHa3XRgMJiM34hIOZU6xf6rjEgkN2Geq24u1b\nhUW8URb+5dcasQ9iIfkNn3R+zK5PzyvQNf6+XrbVjpLqPHXJYrD85EKlXkPqiE6y\n3ehYMrIaZIY6gMuIVcg8AEtsm5EwQY7ETw4YnMQLKfyweLsHEQKCAQEA5vavDyQj\nn6PqfF1Ntr3N/FfwRr/167HB+/3wHT+FwRpCw62ACeBC0iFXmzG2wfQfot60fUGa\nQEJiUDGZFvBM0tiTpzmgGG7QpRbPe1919Sl5LZeLA9bngRnmqn5zAkmVTeBCO/4F\nMSk9hnBZ0v0W3DqNmjuIH298g3gl4VJeKpILd62LbhjvhjT/LXlekYDEj3p9Xob8\n1OQxFJgftFyg4P07RRaUzsNLhqEdY3VxDcUMb9459fEYeb7sYig+zVPaZQ31aMVK\nj6K+XiH5M5uKJWkPdMDUG84jreFAdBY9kGCuSulTWgmTLlMKSI85q5hkckY2EQQL\n5u456xfyuFcnEwKCAQEA2bCCcqcGIAiMwk/6z7XIJeUsSUg+ObvkEdogk5n6Y1Ea\nt5LxMpQzhG6SHJ2f38VyKgv9e/jnwXI8eiejper6OeQEBG4+AedcLYi0V5SUMIgD\nX4bxT9+qCwYrwt9YHkJySk237WZUWJPVfxHg0vqNYyD/CXBowx0nm8jEuZ8iT+CW\nO2uZq+0DO2WqoYT54lZux6aEzm+oAkzwJJVXJcUVPg7bJXK1ObOzvHpkZJxHL8+S\nKufzew/CXALKWHoCkEP/P8b7oxjcjQI3KK0EM2fABNvN28+qscqTqQjfAsNw24Ob\nP8rL8amgd/x7iddIbEpOSoLAH1gVoxJXA0oqkC6YmQKCAQEAiIeoomW1nUgTdCLf\nrrfyzUnaoqgVIpf42RKa319OnQD+GJg2iSAFwBuvovE3XN4H2YqW3Thri7LyVP+M\nxM+WSkl2tzLMXcUcF4staXvbyeoTVQ0xQzrFrT53aa/IIsEGvntkC/y0awQ6937w\nylWMLvF6BYNNi2+nBjx+//xl5/pfRwbS1mltJkOr2ODXM2IQT9STyc44JU0jak4m\n58Kd44IuiD+6BaPSwKn7KnEhPIeQO4z9bFJyKn3fVIL/5Pa9smEXAjEmS1Rj/ldM\n7eHzPvwlA9p9SFaKJt5x8G25ROCyB1x4RlBEreyutofcCoDSV+8DRPnEY2XN3RhS\nBgCW+wKCAQAyHrqaDSyS2YUXA/UaN59CYlZk9PYmssTa+16+vRfyH+1H0NQpsgd+\neTq4ze3ORpZ3adVN4svxNQ0JjvDVtZkxFPd70aoDJDKL5UqoU3QfDGHCb75FhpiO\n+ze+IVAXf3Ly+pvbU9Edp8PjAsnBqaA9743orXHhYmgJLRtmJWZv/6R3P9ncxLAW\nz9yOXaBu5TmSTBuNsBV9mhs8QQoUjyDJ7f+0yolBJMfAIGnW5EhbkK31pPvhHIrC\nRn4yCr1mW9F77KNpNMMq0BTFD7jE4SFLvRPThSem0Z5Xr8wwxbDJSa7H7DgyhryE\ng6Qp42AwVpdZ/mqfjNdGeWWBQ2UzVxcZAoIBAHNXgjD3umcKciYRAbltNJrXx9xk\ndAv8I69oEMCy4hCmvKUjy/UI9NqXFjBb/G6VGgh6NUE9o9o27t1Y5Plm0izyCA1M\nDFruaRfjyJ8qjbEifcqRtcF3rzsBiXIwdmbN6qT4PUipN2elpUAd7J1OIwGIIe3u\nCWNyOTNL+2+oQ/Eg1Y99mg3yrsVyOwhynVE80/X5cy07bXXR5rv1x4NKSVbPhlnt\nL6J5iAoqoDKICzjcgF5x3mj9YFWZrC3aRxRrN5RoEgeVdcXeK56UJqXHjmKN++m3\nc8OPEIBZiD8UJuhSNSOLiBFrGz6toy6rpHavqqknGhVWotXsAs1h8LNkBe8=\n-----END RSA PRIVATE KEY-----" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + } + ) { + id + } + CiFeaturesGroup3: addGroupsToProject( + input: { + project: { + name: "ci-features-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CIFeaturesEnv1: addOrUpdateEnvironment( + input: { + id: 2002 + name: "lagoon-api-variables" + project: 2012 + deployType: BRANCH + deployBaseRef: "lagoon-api-variables" + environmentType: PRODUCTION + openshiftProjectName: "ci-features-control-k8s-lagoon-api-variables" + } + ) { + id + } + + CIFeaturesEnvVars1: addEnvVariable( + input: { + type: PROJECT + typeId: 2012 + name: "LAGOON_API_VARIABLE_PROJECT" + value: "4A65DC68F2" + } + ) { + id + } + + CIFeaturesEnvVars2: addEnvVariable( + input: { + type: PROJECT + typeId: 2012 + name: "LAGOON_API_VARIABLE_OVERRIDE" + value: "74B3E42B54" + } + ) { + id + } + + CIFeaturesEnvVars3: addEnvVariable( + input: { + type: ENVIRONMENT + typeId: 2002 + name:"LAGOON_API_VARIABLE_ENVIRONMENT" + value: "EA2AFAE09B" + } + ) { + id + value + } + + CIFeaturesEnvVars4: addEnvVariable( + input: { + type: ENVIRONMENT + typeId: 2002 + name: "LAGOON_API_VARIABLE_OVERRIDE" + value: "D0CE76D4C9" + } + ) { + id + } + + CIFeaturesEnvVars5: addEnvVariable( + input: { + type: PROJECT + typeId: 2012 + name: "LAGOON_API_VARIABLE_BUILD" + value: "AEF177FCF4" + scope: BUILD + } + ) { + id + } + + CIFeaturesEnvVars6: addEnvVariable( + input: { + type: PROJECT + typeId: 2012 + name: "LAGOON_API_VARIABLE_RUNTIME" + value: "90AEC657F8" + scope: RUNTIME + } + ) { + id + } + + CIFeaturesEnvVars7: addEnvVariable( + input: { + type: PROJECT + typeId: 2012 + name: "LAGOON_API_VARIABLE_MULTILINE_SPACED" + value: "-----BEGIN PUBLIC KEY-----\\\nB10B03D8DB7F\\\n-----END PUBLIC KEY-----" + } + ) { + id + } + + CiFeaturesRocketChat: addNotificationToProject( + input: { + project: "ci-features-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiFeaturesEmail: addNotificationToProject( + input: { + project: "ci-features-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiFeaturesSubfolder: addProject( + input: { + id: 2017 + name: "ci-features-subfolder-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/features-subfolder.git" + productionEnvironment: "master" + subfolder: "subfolder1/subfolder2" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + + CiFeaturesSubfolderGroup3: addGroupsToProject( + input: { + project: { + name: "ci-features-subfolder-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + + CiFeaturesSubfolderRocketChat: addNotificationToProject( + input: { + project: "ci-features-subfolder-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiFeaturesSubfolderEmail: addNotificationToProject( + input: { + project: "ci-features-subfolder-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiElasticsearch: addProject( + input: { + id: 2014 + name: "ci-elasticsearch-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/elasticsearch.git" + productionEnvironment: "master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiElasticsearchGroup3: addGroupsToProject( + input: { + project: { + name: "ci-elasticsearch-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiElasticsearchRocketChat: addNotificationToProject( + input: { + project: "ci-elasticsearch-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiElasticsearchEmail: addNotificationToProject( + input: { + project: "ci-elasticsearch-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiDrupalPostgres: addProject( + input: { + id: 2016 + name: "ci-drupal-postgres-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/drupal-postgres.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiDrupalPostgresGroup3: addGroupsToProject( + input: { + project: { + name: "ci-drupal-postgres-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiDrupalPostgresRocketChat: addNotificationToProject( + input: { + project: "ci-drupal-postgres-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiDrupalPostgresEmail: addNotificationToProject( + input: { + project: "ci-drupal-postgres-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiSolr: addProject( + input: { + id: 2020 + name: "ci-solr-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/solr.git" + productionEnvironment:"master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiSolrGroup3: addGroupsToProject( + input: { + project: { + name: "ci-solr-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiSolrRocketChat: addNotificationToProject( + input: { + project: "ci-solr-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiSolrEmail: addNotificationToProject( + input: { + project: "ci-solr-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + CiApi: addProject( + input: { + id: 2021 + name: "ci-api-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@172.17.0.1:2222/git/api.git" + productionEnvironment: "master" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiApiGroup3: addGroupsToProject( + input: { + project: { + name: "ci-api-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiApiRocketChat: addNotificationToProject( + input: { + project: "ci-api-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiApiEmail: addNotificationToProject( + input: { + project: "ci-api-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + + + + CILimit: addProject( + input: { + id: 2019 + name: "ci-env-limit-control-k8s" + productionEnvironment: "master" + openshift: 2001 + developmentEnvironmentsLimit: 2 + gitUrl: "ssh://git@172.17.0.1:2222/git/node.git" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + + CILimitGroup3: addGroupsToProject( + input: { + project: { + name: "ci-env-limit-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + + CILimitEnv1: addOrUpdateEnvironment( + input: { + id: 2007 + name: "master" + project: 2019 + deployType: BRANCH + deployBaseRef: "master" + environmentType: PRODUCTION + openshiftProjectName: "ci-env-limit" + } + ) { + id + } + + CILimitEnv2: addOrUpdateEnvironment( + input: { + id: 2008 + name: "develop" + project: 2019 + deployType: BRANCH + deployBaseRef: "develop" + environmentType: DEVELOPMENT + openshiftProjectName: "ci-env-limit" + } + ) { + id + } + + CILimitEn3: addOrUpdateEnvironment( + input: { + id: 2009 + name: "stage" + project: 2019 + deployType: BRANCH + deployBaseRef: "stage" + environmentType: DEVELOPMENT + openshiftProjectName: "ci-env-limit" + } + ) { + id + } + + CIPicky: addProject( + input: { + id: 2013 + name: "ci-branch-picky-control-k8s" + productionEnvironment: "master" + openshift: 2001 + branches: "^feature/|^(dev|test|develop|master)$" + developmentEnvironmentsLimit: 5 + gitUrl: "ssh://git@172.17.0.1:2222/git/node.git" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + + CIPickyGroup1: addGroupsToProject( + input: { + project: { + name: "ci-branch-picky-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + + CIPickyEnv1: addOrUpdateEnvironment( + input: { + id: 20010 + name: "master" + project: 2013 + deployType: BRANCH + deployBaseRef: "master" + environmentType: PRODUCTION + openshiftProjectName: "ci-branch-picky" + } + ) { + id + } + + CIPickyEnv2: addOrUpdateEnvironment( + input: { + id: 20011 + name: "develop" + project: 2013 + deployType: BRANCH + deployBaseRef: "develop" + environmentType: DEVELOPMENT + openshiftProjectName: "ci-branch-picky" + } + ) { + id + } + + CIPickyEn3: addOrUpdateEnvironment( + input: { + id: 20012 + name: "stage" + project: 2013 + deployType: BRANCH + deployBaseRef: "stage" + environmentType: DEVELOPMENT + openshiftProjectName: "ci-branch-picky" + } + ) { + id + } + + CIPickyEn4: addOrUpdateEnvironment( + input: { + id: 20013 + name: "banana" + project: 2013 + deployType: BRANCH + deployBaseRef: "banana" + environmentType: DEVELOPMENT + openshiftProjectName: "ci-branch-picky" + } + ) { + id + } + + CiActiveStandby: addProject( + input: { + id: 2024 + name: "ci-active-standby-control-k8s" + openshift: 2001 + gitUrl: "ssh://git@192.168.42.1:2222/git/active-standby.git" + productionEnvironment:"master-a" + standbyProductionEnvironment:"master-b" + activeSystemsTask: "lagoon_controllerJob" + activeSystemsMisc: "lagoon_controllerMisc" + activeSystemsDeploy: "lagoon_controllerBuildDeploy" + activeSystemsRemove: "lagoon_controllerRemove" + privateKey: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + } + ) { + id + } + CiActiveStandbyGroup3: addGroupsToProject( + input: { + project: { + name: "ci-active-standby-control-k8s" + } + groups: [ + { + name: "ci-group" + } + ] + } + ) { + id + } + CiActiveStandbyRocketChat: addNotificationToProject( + input: { + project: "ci-active-standby-control-k8s" + notificationType: ROCKETCHAT + notificationName: "amazeeio--lagoon-local-ci" + } + ) { + id + } + CiActiveStandbyEmail: addNotificationToProject( + input: { + project: "ci-active-standby-control-k8s" + notificationType: EMAIL + notificationName: "local-email-testing" + } + ) { + id + } + +} diff --git a/node-packages/commons/src/api.ts b/node-packages/commons/src/api.ts index ee2199a88c..b79c55ec81 100644 --- a/node-packages/commons/src/api.ts +++ b/node-packages/commons/src/api.ts @@ -1112,6 +1112,7 @@ fragment on Deployment { started completed remoteId + uiLink environment { name } diff --git a/node-packages/commons/src/tasks.ts b/node-packages/commons/src/tasks.ts index fb61685893..91d50af756 100644 --- a/node-packages/commons/src/tasks.ts +++ b/node-packages/commons/src/tasks.ts @@ -1,3 +1,4 @@ +import * as R from 'ramda'; import { connect, AmqpConnectionManager, @@ -5,7 +6,18 @@ import { } from 'amqp-connection-manager'; import { ConfirmChannel, ConsumeMessage } from 'amqplib'; import { logger } from './local-logging'; -import { getActiveSystemForProject, getEnvironmentsForProject } from './api'; +import { + getActiveSystemForProject, + getEnvironmentsForProject, + getOpenShiftInfoForProject, + getBillingGroupForProject, + addOrUpdateEnvironment, + getEnvironmentByName, + addDeployment +} from './api'; +import sha1 from 'sha1'; +import crypto from 'crypto'; +import moment from 'moment'; interface MessageConsumer { (msg: ConsumeMessage): Promise; @@ -74,6 +86,18 @@ const rabbitmqPassword = process.env.RABBITMQ_PASSWORD || 'guest'; const taskPrefetch = process.env.TASK_PREFETCH_COUNT ? Number(process.env.TASK_PREFETCH_COUNT) : 2; const taskMonitorPrefetch = process.env.TASKMONITOR_PREFETCH_COUNT ? Number(process.env.TASKMONITOR_PREFETCH_COUNT) : 1; +// these are required for the builddeploydata creation +// they match what are used in the kubernetesbuilddeploy service +const CI = process.env.CI || "false" +const registry = process.env.REGISTRY || "registry.lagoon.svc:5000" +const lagoonGitSafeBranch = process.env.LAGOON_GIT_SAFE_BRANCH || "master" +const lagoonVersion = process.env.LAGOON_VERSION +const lagoonEnvironmentType = process.env.LAGOON_ENVIRONMENT_TYPE || "development" +const overwriteOCBuildDeployDindImage = process.env.OVERWRITE_OC_BUILD_DEPLOY_DIND_IMAGE +const overwriteKubectlBuildDeployDindImage = process.env.OVERWRITE_KUBECTL_BUILD_DEPLOY_DIND_IMAGE +const overwriteActiveStandbyTaskImage = process.env.OVERWRITE_ACTIVESTANDBY_TASK_IMAGE +const jwtSecret = process.env.JWTSECRET || "super-secret-string" + class UnknownActiveSystem extends Error { constructor(message) { super(message); @@ -219,6 +243,265 @@ export const createTaskMonitor = async function(task: string, payload: any) { return sendToLagoonTasksMonitor(task, payload); } +// makes strings "safe" if it is to be used in something dns related +const makeSafe = string => string.toLocaleLowerCase().replace(/[^0-9a-z-]/g,'-') + +// This is used to replace the functionality in `kubernetesbuilddeploy` to handle sending the required information +// directly to the message queue for the controllers to consume +// @TODO: make sure if it fails, it does so properly +const getOperatorBuildData = async function(deployData: any) { + const { + projectName, + branchName, + sha, + type, + pullrequestTitle, + headBranchName: headBranch, + headSha, + baseBranchName: baseBranch, + baseSha, + promoteSourceEnvironment + } = deployData; + + const project = await getActiveSystemForProject(projectName, 'Deploy'); + // const environments = await getEnvironmentsForProject(projectName); + + var environmentName = makeSafe(branchName) + + const result = await getOpenShiftInfoForProject(projectName); + const projectOpenShift = result.project + const billingGroupResult = await getBillingGroupForProject(projectName); + const projectBillingGroup = billingGroupResult.project + + var overlength = 58 - projectName.length; + if ( environmentName.length > overlength ) { + var hash = sha1(environmentName).substring(0,4) + environmentName = environmentName.substring(0, overlength-5) + environmentName = environmentName.concat('-' + hash) + } + + var environmentType = 'development' + if ( + projectOpenShift.productionEnvironment === environmentName + || projectOpenShift.standbyProductionEnvironment === environmentName + ) { + environmentType = 'production' + } + var gitSha = sha as string + var projectTargetName = projectOpenShift.openshift.name + var openshiftProject = projectOpenShift.openshiftProjectPattern ? projectOpenShift.openshiftProjectPattern.replace('${environment}',environmentName).replace('${project}', projectName) : `${projectName}-${environmentName}` + var deployPrivateKey = projectOpenShift.privateKey + var gitUrl = projectOpenShift.gitUrl + var projectProductionEnvironment = projectOpenShift.productionEnvironment + var projectStandbyEnvironment = projectOpenShift.standbyProductionEnvironment + var subfolder = projectOpenShift.subfolder || "" + var routerPattern = projectOpenShift.openshift.routerPattern ? projectOpenShift.openshift.routerPattern.replace('${environment}',environmentName).replace('${project}', projectName) : "" + var prHeadBranch = headBranch || "" + var prHeadSha = headSha || "" + var prBaseBranch = baseBranch || "" + var prBaseSha = baseSha || "" + var prPullrequestTitle = pullrequestTitle || "" + var prPullrequestNumber = branchName.replace('pr-','') + var graphqlEnvironmentType = environmentType.toUpperCase() + var graphqlGitType = type.toUpperCase() + var openshiftPromoteSourceProject = promoteSourceEnvironment ? `${projectName}-${makeSafe(promoteSourceEnvironment)}` : "" + // A secret which is the same across all Environments of this Lagoon Project + var projectSecret = crypto.createHash('sha256').update(`${projectName}-${jwtSecret}`).digest('hex'); + var alertContactHA = "" + var alertContactSA = "" + var monitoringConfig = JSON.parse(projectOpenShift.openshift.monitoringConfig) || "invalid" + if (monitoringConfig != "invalid"){ + alertContactHA = monitoringConfig.uptimerobot.alertContactHA || "" + alertContactSA = monitoringConfig.uptimerobot.alertContactSA || "" + } + var availability = projectOpenShift.availability || "STANDARD" + + var alertContact = "" + if (alertContactHA != undefined && alertContactSA != undefined){ + if (availability == "HIGH") { + alertContact = alertContactHA + } else { + alertContact = alertContactSA + } + } else { + alertContact = "unconfigured" + } + const billingGroup = projectBillingGroup.groups.find(i => i.type == "billing" ) || "" + var uptimeRobotStatusPageId = billingGroup.uptimeRobotStatusPageId || "" + + var branchData: any = {}; + var pullrequestData: any = {}; + var promoteData: any = {}; + + switch (type) { + case "branch": + // if we have a sha given, we use that, if not we fall back to the branch (which needs be prefixed by `origin/` + var gitRef = gitSha ? gitSha : `origin/${branchName}` + var deployBaseRef = branchName + var deployHeadRef = null + var deployTitle = null + branchData = { + branch: { + name: branchName, + }, + }; + break; + case "pullrequest": + var gitRef = gitSha + var deployBaseRef = prBaseBranch + var deployHeadRef = prHeadBranch + var deployTitle = prPullrequestTitle + pullrequestData = { + pullrequest: { + headBranch: prHeadBranch, + headSha: prHeadSha, + baseBranch: prBaseBranch, + baseSha: prBaseSha, + title: prPullrequestTitle, + number: prPullrequestNumber, + }, + }; + break; + case "promote": + var gitRef = `origin/${promoteSourceEnvironment}` + var deployBaseRef = promoteSourceEnvironment + var deployHeadRef = null + var deployTitle = null + promoteData = { + promote: { + sourceEnvironment: promoteSourceEnvironment, + sourceProject: openshiftPromoteSourceProject, + } + }; + break; + } + + // @TODO: openshiftProject here can't be generated on the cluster side (it should be) but the addOrUpdate mutation doesn't allow for openshiftProject to be optional + // maybe need to have this generate a random uid initially? + let environment; + try { + environment = await addOrUpdateEnvironment(branchName, projectOpenShift.id, graphqlGitType, deployBaseRef, graphqlEnvironmentType, openshiftProject, deployHeadRef, deployTitle) + logger.info(`${openshiftProject}: Created/Updated Environment in API`) + } catch (err) { + logger.error(err) + throw new Error + } + + const randBuildId = Math.random().toString(36).substring(7); + const buildName = `lagoon-build-${randBuildId}`; + + let deployment; + try { + const now = moment.utc(); + const apiEnvironment = await getEnvironmentByName(branchName, projectOpenShift.id); + deployment = await addDeployment(buildName, "NEW", now.format('YYYY-MM-DDTHH:mm:ss'), apiEnvironment.environmentByName.id); + } catch (error) { + logger.error(`Could not save deployment for project ${projectOpenShift.id}. Message: ${error}`); + } + + let buildImage = {} + // During CI we want to use the OpenShift Registry for our build Image and use the OpenShift registry for the base Images + // Since the Operator could eventually support openshift, we can handle which image to supply here + if (CI == "true") { + switch (project.activeSystemsDeploy) { + case 'lagoon_openshiftBuildDeploy': + buildImage = "172.17.0.1:5000/lagoon/oc-build-deploy-dind:latest" + break; + default: + // default to the kubectl builddeploy dind since the controllers and kubernetes use the same underlying process + buildImage = "172.17.0.1:5000/lagoon/kubectl-build-deploy-dind:latest" + } + } else if (overwriteOCBuildDeployDindImage) { + // allow to overwrite the image we use via OVERWRITE_OC_BUILD_DEPLOY_DIND_IMAGE env variable + // this needs to be added to the `api` deployment/pods to be used + switch (project.activeSystemsDeploy) { + case 'lagoon_openshiftBuildDeploy': + buildImage = overwriteOCBuildDeployDindImage + break; + } + } else if (overwriteKubectlBuildDeployDindImage) { + // allow to overwrite the image we use via OVERWRITE_KUBECTL_BUILD_DEPLOY_DIND_IMAGE env variable + // this needs to be added to the `api` deployment/pods to be used + switch (project.activeSystemsDeploy) { + case 'lagoon_controllerBuildDeploy': + case 'lagoon_kubernetesBuildDeploy': + buildImage = overwriteKubectlBuildDeployDindImage + break; + } + } else if (lagoonEnvironmentType == 'production') { + // we are a production environment, use the amazeeio/ image with our current lagoon version + switch (project.activeSystemsDeploy) { + case 'lagoon_openshiftBuildDeploy': + buildImage = `amazeeio/oc-build-deploy-dind:${lagoonVersion}` + break; + default: + // default to the kubectl builddeploy dind since the controllers and kubernetes use the same underlying process + buildImage = `amazeeio/kubectl-build-deploy-dind:${lagoonVersion}` + } + } else { + // we are a development enviornment, use the amazeeiolagoon image with the same branch name + buildImage = `amazeeiolagoon/kubectl-build-deploy-dind:${lagoonGitSafeBranch}` + switch (project.activeSystemsDeploy) { + case 'lagoon_openshiftBuildDeploy': + buildImage = `amazeeiolagoon/oc-build-deploy-dind:${lagoonGitSafeBranch}` + break; + default: + // default to the kubectl builddeploy dind since the controllers and kubernetes use the same underlying process + buildImage = `amazeeiolagoon/kubectl-build-deploy-dind:${lagoonGitSafeBranch}` + } + } + + var gitRef = gitSha ? gitSha : `origin/${branchName}` + + // encode some values so they get sent to the controllers nicely + const sshKeyBase64 = new Buffer(deployPrivateKey.replace(/\\n/g, "\n")).toString('base64') + const envVars = new Buffer(JSON.stringify(environment.addOrUpdateEnvironment.envVariables)).toString('base64') + const projectVars = new Buffer(JSON.stringify(projectOpenShift.envVariables)).toString('base64') + + // this is what will be returned and sent to the controllers via message queue, it is the lagoonbuild controller spec + var buildDeployData: any = { + metadata: { + name: buildName, + namespace: "lagoon", + }, + spec: { + build: { + type: type, + image: buildImage, + ci: CI, + }, + ...branchData, + ...pullrequestData, + ...promoteData, + gitReference: gitRef, + project: { + name: projectName, + gitUrl: gitUrl, + uiLink: deployment.addDeployment.uiLink, + environment: environmentName, + environmentType: environmentType, + productionEnvironment: projectProductionEnvironment, + standbyEnvironment: projectStandbyEnvironment, + subfolder: subfolder, + routerPattern: routerPattern, + deployTarget: projectTargetName, + projectSecret: projectSecret, + key: sshKeyBase64, + registry: registry, + monitoring: { + contact: alertContact, + statuspageID: uptimeRobotStatusPageId, + }, + variables: { + project: projectVars, + environment: envVars, + }, + }, + } + }; + return buildDeployData; +} + export const createDeployTask = async function(deployData: any) { const { projectName, @@ -246,6 +529,7 @@ export const createDeployTask = async function(deployData: any) { switch (project.activeSystemsDeploy) { case 'lagoon_openshiftBuildDeploy': case 'lagoon_kubernetesBuildDeploy': + case 'lagoon_controllerBuildDeploy': // we want to limit production environments, without making it configurable currently var productionEnvironmentsLimit = 2; @@ -313,6 +597,10 @@ export const createDeployTask = async function(deployData: any) { return sendToLagoonTasks('builddeploy-openshift', deployData); case 'lagoon_kubernetesBuildDeploy': return sendToLagoonTasks('builddeploy-kubernetes', deployData); + case 'lagoon_controllerBuildDeploy': + // controllers uses a different message than the other services, so we need to source it here + const buildDeployData = await getOperatorBuildData(deployData); + return sendToLagoonTasks(buildDeployData.spec.project.deployTarget+':builddeploy', buildDeployData); default: throw new UnknownActiveSystem( `Unknown active system '${project.activeSystemsDeploy}' for task 'deploy' in for project ${projectName}` @@ -327,6 +615,10 @@ export const createDeployTask = async function(deployData: any) { return sendToLagoonTasks('builddeploy-openshift', deployData); case 'lagoon_kubernetesBuildDeploy': return sendToLagoonTasks('builddeploy-kubernetes', deployData); + case 'lagoon_controllerBuildDeploy': + // controllers uses a different message than the other services, so we need to source it here + const buildDeployData = await getOperatorBuildData(deployData); + return sendToLagoonTasks(buildDeployData.spec.project.deployTarget+':builddeploy', buildDeployData); default: throw new UnknownActiveSystem( `Unknown active system '${project.activeSystemsDeploy}' for task 'deploy' in for project ${projectName}` @@ -354,6 +646,10 @@ export const createDeployTask = async function(deployData: any) { 'builddeploy-kubernetes', deployData ); + case 'lagoon_controllerBuildDeploy': + // controllers uses a different message than the other services, so we need to source it here + const buildDeployData = await getOperatorBuildData(deployData); + return sendToLagoonTasks(buildDeployData.spec.project.deployTarget+':builddeploy', buildDeployData); default: throw new UnknownActiveSystem( `Unknown active system '${project.activeSystemsDeploy}' for task 'deploy' in for project ${projectName}` @@ -380,6 +676,10 @@ export const createDeployTask = async function(deployData: any) { return sendToLagoonTasks('builddeploy-openshift', deployData); case 'lagoon_kubernetesBuildDeploy': return sendToLagoonTasks('builddeploy-kubernetes', deployData); + case 'lagoon_controllerBuildDeploy': + // controllers uses a different message than the other services, so we need to source it here + const buildDeployData = await getOperatorBuildData(deployData); + return sendToLagoonTasks(buildDeployData.spec.project.deployTarget+':builddeploy', buildDeployData); default: throw new UnknownActiveSystem( `Unknown active system '${ @@ -396,6 +696,10 @@ export const createDeployTask = async function(deployData: any) { return sendToLagoonTasks('builddeploy-openshift', deployData); case 'lagoon_kubernetesBuildDeploy': return sendToLagoonTasks('builddeploy-kubernetes', deployData); + case 'lagoon_controllerBuildDeploy': + // controllers uses a different message than the other services, so we need to source it here + const buildDeployData = await getOperatorBuildData(deployData); + return sendToLagoonTasks(buildDeployData.spec.project.deployTarget+':builddeploy', buildDeployData); default: throw new UnknownActiveSystem( `Unknown active system '${ @@ -423,6 +727,10 @@ export const createDeployTask = async function(deployData: any) { return sendToLagoonTasks('builddeploy-openshift', deployData); case 'lagoon_kubernetesBuildDeploy': return sendToLagoonTasks('builddeploy-kubernetes', deployData); + case 'lagoon_controllerBuildDeploy': + // controllers uses a different message than the other services, so we need to source it here + const buildDeployData = await getOperatorBuildData(deployData); + return sendToLagoonTasks(buildDeployData.spec.project.deployTarget+':builddeploy', buildDeployData); default: throw new UnknownActiveSystem( `Unknown active system '${ @@ -632,6 +940,70 @@ export const createRemoveTask = async function(removeData: any) { } break; + // handle removals using the controllers, send the message to our specific target cluster queue + case 'lagoon_controllerRemove': + const result = await getOpenShiftInfoForProject(projectName); + const deployTarget = result.project.openshift.name + if (type === 'branch') { + // Check to ensure the environment actually exists. + let foundEnvironment = false; + allEnvironments.project.environments.forEach(function( + environment, + index + ) { + if (environment.name === branch) { + foundEnvironment = true; + } + }); + + if (!foundEnvironment) { + logger.debug( + `projectName: ${projectName}, branchName: ${branch}, no environment found.` + ); + throw new NoNeedToRemoveBranch( + 'Branch environment does not exist, no need to remove anything.' + ); + } + + logger.debug( + `projectName: ${projectName}, branchName: ${branchName}. Removing branch environment.` + ); + // use the targetname as the routing key with the action + return sendToLagoonTasks(deployTarget+":remove", removeData); + } else if (type === 'pullrequest') { + // Work out the branch name from the PR number. + let branchName = 'pr-' + pullrequestNumber; + removeData.branchName = 'pr-' + pullrequestNumber; + + // Check to ensure the environment actually exists. + let foundEnvironment = false; + allEnvironments.project.environments.forEach(function( + environment, + index + ) { + if (environment.name === branchName) { + foundEnvironment = true; + } + }); + + if (!foundEnvironment) { + logger.debug( + `projectName: ${projectName}, pullrequest: ${branchName}, no pullrequest found.` + ); + throw new NoNeedToRemoveBranch( + 'Pull Request environment does not exist, no need to remove anything.' + ); + } + + logger.debug( + `projectName: ${projectName}, pullrequest: ${branchName}. Removing pullrequest environment.` + ); + return sendToLagoonTasks(deployTarget+":remove", removeData); + } else if (type === 'promote') { + return sendToLagoonTasks(deployTarget+":remove", removeData); + } + break; + default: throw new UnknownActiveSystem( `Unknown active system '${project.activeSystemsRemove}' for task 'remove' in for project ${projectName}` @@ -639,6 +1011,56 @@ export const createRemoveTask = async function(removeData: any) { } } +// creates the restore job configuration for use in the misc task +const restoreConfig = (name, backupId, safeProjectName) => { + let config = { + apiVersion: 'backup.appuio.ch/v1alpha1', + kind: 'Restore', + metadata: { + name + }, + spec: { + snapshot: backupId, + restoreMethod: { + s3: {}, + }, + backend: { + s3: { + bucket: `baas-${safeProjectName}` + }, + repoPasswordSecretRef: { + key: 'repo-pw', + name: 'baas-repo-pw' + }, + }, + }, + }; + + return config; +}; + +// creates the route/ingress migration config +const migrateIngress = (destinationNamespace, sourceNamespace) => { + const randId = Math.random().toString(36).substring(7); + const migrateName = `ingress-migrate-${randId}`; + let config = { + apiVersion: 'dioscuri.amazee.io/v1', + kind: 'IngressMigrate', + metadata: { + name: migrateName, + annotations: { + 'dioscuri.amazee.io/migrate':'true' + } + }, + spec: { + destinationNamespace: destinationNamespace, + activeEnvironment: sourceNamespace, + }, + }; + + return config; +}; + export const createTaskTask = async function(taskData: any) { const { project } = taskData; @@ -657,6 +1079,13 @@ export const createTaskTask = async function(taskData: any) { case 'lagoon_kubernetesJob': return sendToLagoonTasks('job-kubernetes', taskData); + case 'lagoon_controllerJob': + // since controllers queues are named, we have to send it to the right tasks queue + // do that here + const result = await getOpenShiftInfoForProject(project.name); + const deployTarget = result.project.openshift.name + return sendToLagoonTasks(deployTarget+":jobs", taskData); + default: throw new UnknownActiveSystem( `Unknown active system '${projectSystem.activeSystemsTask}' for 'task' for project ${project.name}` @@ -683,7 +1112,83 @@ export const createMiscTask = async function(taskData: any) { updatedKey = `kubernetes:${key}`; taskId = 'misc-kubernetes'; break; - + case 'lagoon_controllerMisc': + // handle any controller based misc tasks + updatedKey = `kubernetes:${key}`; + taskId = 'misc-kubernetes'; + // determine the deploy target (openshift/kubernetes) for the task to go to + const result = await getOpenShiftInfoForProject(project.name); + const projectOpenShift = result.project + var deployTarget = projectOpenShift.openshift.name + // this is the json structure for sending a misc task to the controller + // there are some additional bits that can be adjusted, and these are done in the switch below on `updatedKey` + var miscTaskData: any = { + misc: {}, + key: updatedKey, + environment: { + name: taskData.data.environment.name, + openshiftProjectName: taskData.data.environment.openshiftProjectName + }, + project: { + name: taskData.data.project.name + }, + task: taskData.data.task, + advancedTask: {} + } + switch (updatedKey) { + case 'kubernetes:restic:backup:restore': + // Handle setting up the configuration for a restic restoration task + const restoreName = `restore-${R.slice(0, 7, taskData.data.backup.backupId)}`; + // generate the restore CRD + const restoreConf = restoreConfig(restoreName, taskData.data.backup.backupId, makeSafe(taskData.data.project.name)) + // base64 encode it + const restoreBytes = new Buffer(JSON.stringify(restoreConf).replace(/\\n/g, "\n")).toString('base64') + miscTaskData.misc.miscResource = restoreBytes + break; + case 'kubernetes:route:migrate': + // handle setting up the task configuration for running the active/standby switch + // this uses the `advanced task` system in the controllers + // first generate the migration CRD + const migrateConf = migrateIngress( + makeSafe(taskData.data.productionEnvironment.openshiftProjectName), + makeSafe(taskData.data.environment.openshiftProjectName)) + // generate out custom json payload to send to the advanced task + var jsonPayload: any = { + productionEnvironment: taskData.data.productionEnvironment.name, + standbyEnvironment: taskData.data.environment.name, + crd: migrateConf + } + // encode it + const jsonPayloadBytes = new Buffer(JSON.stringify(jsonPayload).replace(/\\n/g, "\n")).toString('base64') + // set the task data up + miscTaskData.advancedTask.JSONPayload = jsonPayloadBytes + // use this image to run the task + let taskImage = "" + // choose which task image to use + if (CI == "true") { + taskImage = "172.17.0.1:5000/lagoon/task-activestandby:latest" + } else if (overwriteActiveStandbyTaskImage) { + // allow to overwrite the image we use via OVERWRITE_ACTIVESTANDBY_TASK_IMAGE env variable + taskImage = overwriteActiveStandbyTaskImage + } else if (lagoonEnvironmentType == 'production') { + taskImage = `amazeeio/task-activestandby:${lagoonVersion}` + } else { + // we are a development enviornment, use the amazeeiolagoon image with the same branch name + taskImage = `amazeeiolagoon/task-activestandby:${lagoonGitSafeBranch}` + } + miscTaskData.advancedTask.runnerImage = taskImage + // miscTaskData.advancedTask.runnerImage = "shreddedbacon/runner:latest" + break; + case 'kubernetes:build:cancel': + // build cancellation is just a standard unmodified message + miscTaskData.misc = taskData.data.build + break; + default: + miscTaskData.misc = taskData.data.build + break; + } + // send the task to the queue + return sendToLagoonTasks(deployTarget+':misc', miscTaskData); default: break; } diff --git a/openshift-setup/dbaas-providers.yaml b/openshift-setup/dbaas-providers.yaml index 6bb3df1bbd..edeb87bbaa 100644 --- a/openshift-setup/dbaas-providers.yaml +++ b/openshift-setup/dbaas-providers.yaml @@ -4,9 +4,9 @@ metadata: name: mariadbprovider-development spec: environment: development - hostname: 172.17.0.1.xip.io + hostname: 172.17.0.1.nip.io readReplicaHostnames: - - 172.17.0.1.xip.io + - 172.17.0.1.nip.io password: password port: '3306' user: root @@ -17,9 +17,9 @@ metadata: name: mariadbprovider-production spec: environment: production - hostname: 172.17.0.1.xip.io + hostname: 172.17.0.1.nip.io readReplicaHostnames: - - 172.17.0.1.xip.io + - 172.17.0.1.nip.io password: password port: '3306' user: root \ No newline at end of file diff --git a/services/api/src/resolvers.js b/services/api/src/resolvers.js index d7e852ead3..1e14a25454 100644 --- a/services/api/src/resolvers.js +++ b/services/api/src/resolvers.js @@ -47,6 +47,7 @@ const { const { getTasksByEnvironmentId, getTaskByRemoteId, + getTaskById, addTask, deleteTask, updateTask, @@ -299,6 +300,7 @@ const resolvers = { userCanSshToEnvironment, deploymentByRemoteId: getDeploymentByRemoteId, taskByRemoteId: getTaskByRemoteId, + taskById: getTaskById, allProjects: getAllProjects, allOpenshifts: getAllOpenshifts, allEnvironments: getAllEnvironments, diff --git a/services/api/src/resources/deployment/resolvers.ts b/services/api/src/resources/deployment/resolvers.ts index 3fc893555b..16e8d02879 100644 --- a/services/api/src/resources/deployment/resolvers.ts +++ b/services/api/src/resources/deployment/resolvers.ts @@ -22,7 +22,6 @@ import { Helpers as projectHelpers } from '../project/helpers'; import { addTask, } from '@lagoon/commons/dist/api'; -import uuid4 from 'uuid4'; const convertDateFormat = R.init; import { Sql as environmentSql } from '../environment/sql'; @@ -824,18 +823,36 @@ export const switchActiveStandby: ResolverFn = async ( ); const environment = environmentRows[0]; var environmentId = parseInt(environment.id); + // we need to pass some additional information about the production environment + const environmentRowsProd = await query( + sqlClient, + environmentSql.selectEnvironmentByNameAndProject(project.productionEnvironment, project.id), + ); + const environmentProd = environmentRowsProd[0]; + var environmentProdId = parseInt(environmentProd.id); // construct the data for the misc task - let uuid = uuid4(); - + // set up the task data payload const data = { - project, - projectName: project.name, - productionEnvironment: project.productionEnvironment, - standbyProductionEnvironment: project.standbyProductionEnvironment, + project: { + id: project.id, + name: project.name, + productionEnvironment: project.productionEnvironment, + standbyProductionEnvironment: project.standbyProductionEnvironment, + }, + productionEnvironment: { + id: environmentProdId, + name: environmentProd.name, + openshiftProjectName: environmentProd.openshiftProjectName, + }, + environment: { + id: environmentId, + name: environment.name, + openshiftProjectName: environment.openshiftProjectName, + }, task: { - id: 0, - uuid: uuid, + id: "0", + name: "Active/Standby Switch", } }; @@ -849,7 +866,7 @@ export const switchActiveStandby: ResolverFn = async ( 'ACTIVE', created, environmentId, - uuid, + null, null, null, null, @@ -857,7 +874,7 @@ export const switchActiveStandby: ResolverFn = async ( '', false, ); - data.task.id = sourceTaskData.addTask.id + data.task.id = sourceTaskData.addTask.id.toString() // then send the task to openshiftmisc to trigger the migration await createMiscTask({ key: 'route:migrate', data }); @@ -865,7 +882,6 @@ export const switchActiveStandby: ResolverFn = async ( // return the task id and remote id var retData = { id: data.task.id, - remoteId: uuid, environment: environmentId, } return retData; diff --git a/services/api/src/resources/environment/resolvers.ts b/services/api/src/resources/environment/resolvers.ts index 69951f8638..176d8b9079 100644 --- a/services/api/src/resources/environment/resolvers.ts +++ b/services/api/src/resources/environment/resolvers.ts @@ -431,6 +431,7 @@ export const deleteEnvironment: ResolverFn = async ( } = { projectName: project.name, type: environment.deployType, + openshiftProjectName: environment.openshiftProjectName, forceDeleteProductionEnvironment: canDeleteProduction, }; diff --git a/services/api/src/resources/task/resolvers.ts b/services/api/src/resources/task/resolvers.ts index 4b09b5ecfe..2783e619eb 100644 --- a/services/api/src/resources/task/resolvers.ts +++ b/services/api/src/resources/task/resolvers.ts @@ -100,6 +100,33 @@ export const getTaskByRemoteId: ResolverFn = async ( return Helpers(sqlClient).injectLogs(task); }; +export const getTaskById: ResolverFn = async ( + root, + { id }, + { + sqlClient, + hasPermission, + }, +) => { + const queryString = knex('task') + .where('id', '=', id) + .toString(); + + const rows = await query(sqlClient, queryString); + const task = R.prop(0, rows); + + if (!task) { + return null; + } + + const rowsPerms = await query(sqlClient, Sql.selectPermsForTask(task.id)); + await hasPermission('task', 'view', { + project: R.path(['0', 'pid'], rowsPerms), + }); + + return Helpers(sqlClient).injectLogs(task); +}; + export const addTask: ResolverFn = async ( root, { diff --git a/services/api/src/typeDefs.js b/services/api/src/typeDefs.js index eeb7998cbb..1332b585cc 100644 --- a/services/api/src/typeDefs.js +++ b/services/api/src/typeDefs.js @@ -747,6 +747,7 @@ const typeDefs = gql` ): Environment deploymentByRemoteId(id: String): Deployment taskByRemoteId(id: String): Task + taskById(id: Int): Task """ Returns all Project Objects matching given filters (all if no filter defined) """ diff --git a/services/controllerhandler/.gitignore b/services/controllerhandler/.gitignore new file mode 100644 index 0000000000..f06235c460 --- /dev/null +++ b/services/controllerhandler/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/services/controllerhandler/.lagoon.app.yml b/services/controllerhandler/.lagoon.app.yml new file mode 100644 index 0000000000..24648a20d7 --- /dev/null +++ b/services/controllerhandler/.lagoon.app.yml @@ -0,0 +1,109 @@ +apiVersion: v1 +kind: Template +metadata: + creationTimestamp: null + name: lagoon-openshift-template-node +parameters: + - name: SERVICE_NAME + description: Name of this service + required: true + - name: SAFE_BRANCH + description: Which branch this belongs to, special chars replaced with dashes + required: true + - name: SAFE_PROJECT + description: Which project this belongs to, special chars replaced with dashes + required: true + - name: BRANCH + description: Which branch this belongs to, original value + required: true + - name: PROJECT + description: Which project this belongs to, original value + required: true + - name: LAGOON_GIT_SHA + description: git hash sha of the current deployment + required: true + - name: SERVICE_ROUTER_URL + description: URL of the Router for this service + value: "" + - name: OPENSHIFT_PROJECT + description: Name of the Project that this service is in + required: true + - name: REGISTRY + description: Registry where Images are pushed to + required: true + - name: DEPLOYMENT_STRATEGY + description: Strategy of Deploymentconfig + value: "Rolling" + - name: SERVICE_IMAGE + description: Pullable image of service + required: true + - name: CRONJOBS + description: Oneliner of Cronjobs + value: "" +objects: +- apiVersion: v1 + kind: DeploymentConfig + metadata: + creationTimestamp: null + labels: + branch: ${SAFE_BRANCH} + project: ${SAFE_PROJECT} + name: ${SERVICE_NAME} + spec: + replicas: 2 + selector: + service: ${SERVICE_NAME} + strategy: + type: ${DEPLOYMENT_STRATEGY} + template: + metadata: + creationTimestamp: null + labels: + service: ${SERVICE_NAME} + branch: ${SAFE_BRANCH} + project: ${SAFE_PROJECT} + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: service + operator: In + values: + - ${SERVICE_NAME} + topologyKey: kubernetes.io/hostname + containers: + - image: ${SERVICE_IMAGE} + name: ${SERVICE_NAME} + envFrom: + - configMapRef: + name: lagoon-env + env: + - name: RABBITMQ_USERNAME + valueFrom: + secretKeyRef: + name: rabbitmq-username + key: RABBITMQ_USERNAME + - name: RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: rabbitmq-password + key: RABBITMQ_PASSWORD + - name: JWTSECRET + valueFrom: + secretKeyRef: + name: jwtsecret + key: JWTSECRET + - name: SERVICE_NAME + value: ${SERVICE_NAME} + - name: CRONJOBS + value: ${CRONJOBS} + resources: + requests: + cpu: 10m + memory: 10Mi + test: false + triggers: + - type: ConfigChange + status: {} \ No newline at end of file diff --git a/services/controllerhandler/Dockerfile b/services/controllerhandler/Dockerfile new file mode 100644 index 0000000000..f860f00c88 --- /dev/null +++ b/services/controllerhandler/Dockerfile @@ -0,0 +1,29 @@ +ARG LAGOON_GIT_BRANCH +ARG IMAGE_REPO +# STAGE 1: Loading Image lagoon-node-packages-builder which contains node packages shared by all Node Services +FROM ${IMAGE_REPO:-amazeeiolagoon}/yarn-workspace-builder:${LAGOON_GIT_BRANCH:-latest} as yarn-workspace-builder + +# STAGE 2: specific service Image +FROM ${IMAGE_REPO:-amazeeiolagoon}/node:10 + +# Copying generated node_modules from the first stage +COPY --from=yarn-workspace-builder /app /app + +# Setting the workdir to the service, all following commands will run from here +WORKDIR /app/services/controllerhandler/ + +# Copying the .env.defaults into the Workdir, as the dotenv system searches within the workdir for it +COPY --from=yarn-workspace-builder /app/.env.defaults . + +# Copying files from our service +COPY . . + +# Verify that all dependencies have been installed via the yarn-workspace-builder +RUN yarn check --verify-tree + +# Making sure we run in production +ENV NODE_ENV production + +RUN yarn build + +CMD ["yarn", "start"] diff --git a/services/controllerhandler/LICENSE.md b/services/controllerhandler/LICENSE.md new file mode 100644 index 0000000000..79b52093e7 --- /dev/null +++ b/services/controllerhandler/LICENSE.md @@ -0,0 +1,11 @@ +The MIT License (MIT) +===================== + +Copyright (c) 2014 Rod Vagg +--------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/services/controllerhandler/README.md b/services/controllerhandler/README.md new file mode 100644 index 0000000000..3ae4eefdc4 --- /dev/null +++ b/services/controllerhandler/README.md @@ -0,0 +1,3 @@ +# controllerhandler + +This service is called 'controllerhandler', and is part of the amazee.io lagoon deployment system and is responsible for handling messages from remote Lagoon controllers for each task in the rabbitmq queue `lagoon-tasks:controller` diff --git a/services/controllerhandler/package.json b/services/controllerhandler/package.json new file mode 100644 index 0000000000..dd3a5fbebb --- /dev/null +++ b/services/controllerhandler/package.json @@ -0,0 +1,31 @@ +{ + "name": "controllerhandler", + "version": "0.9.0", + "description": "Git Push 2 Ansible Deployment", + "main": "dist/index.js", + "scripts": { + "build": "tsc --build", + "start": "node dist/index", + "dev": "mkdir -p ../../node-packages/commons/dist && NODE_ENV=development nodemon" + }, + "nodemonConfig": { + "ignore": ["../../node-packages/commons/dist/"], + "watch": ["src", "../../node-packages/"], + "ext": "js,ts,json", + "exec": "yarn build --incremental && yarn start --inspect=0.0.0.0:9229" + }, + "author": "amazee.io (http://www.amazee.io)", + "contributors": [ + "Michael Schmid (https://amazee.io)" + ], + "license": "MIT", + "dependencies": { + "@lagoon/commons": "4.0.0", + "kubernetes-client": "^4.0.0", + "ramda": "^0.26.1" + }, + "devDependencies": { + "nodemon": "^1.12.1", + "typescript": "^3.9.3" + } +} diff --git a/services/controllerhandler/src/index.ts b/services/controllerhandler/src/index.ts new file mode 100644 index 0000000000..5908ec461d --- /dev/null +++ b/services/controllerhandler/src/index.ts @@ -0,0 +1,252 @@ +const promisify = require('util').promisify; +import R from 'ramda'; +import { logger } from '@lagoon/commons/dist/local-logging'; +import { + sendToLagoonLogs, + initSendToLagoonLogs +} from '@lagoon/commons/dist/logs'; +import { + consumeTasks, + initSendToLagoonTasks +} from '@lagoon/commons/dist/tasks'; +import { + getOpenShiftInfoForProject, + getEnvironmentByName, + updateEnvironment, + updateDeployment, + getDeploymentByName, + getDeploymentByRemoteId, + setEnvironmentServices, + deleteEnvironment, + updateTask, + updateProject +} from '@lagoon/commons/dist/api'; + +initSendToLagoonLogs(); +initSendToLagoonTasks(); + +const ocsafety = string => + string.toLocaleLowerCase().replace(/[^0-9a-z-]/g, '-'); + +const decode = (str: string):string => Buffer.from(str, 'base64').toString('binary'); + +const updateLagoonTask = async (meta) => { + // Update lagoon task + try { + const convertDateFormat = R.init; + const dateOrNull = R.unless(R.isNil, convertDateFormat) as any; + let completedDate = dateOrNull(meta.endTime) as any; + + if (meta.jobStatus === 'failed') { + completedDate = dateOrNull(meta.endTime); + } + + // transform the jobstatus into one the API knows about + let jobStatus = 'active'; + switch (meta.jobStatus) { + case 'pending': + jobStatus = 'active' + break; + case 'running': + jobStatus = 'active' + break; + case 'complete': + jobStatus = 'succeeded' + break; + default: + jobStatus = meta.jobStatus + break; + } + // update the actual task now + await updateTask(Number(meta.task.id), { + remoteId: meta.remoteId, + status: jobStatus.toUpperCase(), + started: dateOrNull(meta.startTime), + completed: completedDate + }); + } catch (error) { + logger.error( + `Could not update task ${meta.project} ${meta.jobName} ${meta.remoteId}. Message: ${error}` + ); + } +} + +const messageConsumer = async function(msg) { + const { + type, + namespace, + meta, + } = JSON.parse(msg.content.toString()); + + + switch (type) { + case 'build': + logger.verbose( + `Received deployment and environment update task ${meta.buildName} - ${meta.buildPhase}` + ); + try { + let deploymentId; + try { + // try get the ID from our build UID + const deployment = await getDeploymentByRemoteId(meta.remoteId); + if (!deployment.deploymentByRemoteId) { + // otherwise find it using the build name + const deploymentResult = await getDeploymentByName(namespace, meta.buildName); + deploymentId = deploymentResult.environment.deployments[0].id; + } else { + deploymentId = deployment.deploymentByRemoteId.id + } + }catch(error) { + logger.warn(`Error while fetching deployment openshiftproject: ${namespace}: ${error}`) + throw(error) + } + + const convertDateFormat = R.init; + const dateOrNull = R.unless(R.isNil, convertDateFormat) as any; + + await updateDeployment(deploymentId, { + remoteId: meta.remoteId, + status: meta.buildPhase.toUpperCase(), + started: dateOrNull(meta.startTime), + completed: dateOrNull(meta.endTime), + }); + } catch (error) { + logger.error(`Could not update deployment ${meta.project} ${meta.Buildname}. Message: ${error}`); + } + + + let environment; + let project; + try { + const projectResult = await getOpenShiftInfoForProject(meta.project); + project = projectResult.project + + const environmentResult = await getEnvironmentByName(meta.environment, project.id) + environment = environmentResult.environmentByName + } catch (err) { + logger.warn(`${namespace} ${meta.buildName}: Error while getting project or environment information, Error: ${err}. Continuing without update`) + } + + try { + await updateEnvironment( + environment.id, + `{ + openshiftProjectName: "${namespace}", + }` + ); + } catch (err) { + logger.warn(`${namespace} ${meta.buildName}: Error while updating openshiftProjectName in API, Error: ${err}. Continuing without update`) + } + // Update GraphQL API if the Environment has completed or failed + switch (meta.buildPhase) { + case 'complete': + case 'failed': + case 'cancelled': + try { + // update the environment with the routes etc + await updateEnvironment( + environment.id, + `{ + route: "${meta.route}", + routes: "${meta.routes}", + monitoringUrls: "${meta.monitoringUrls}", + project: ${project.id} + }` + ); + // update the environment with the services available + await setEnvironmentServices(environment.id, meta.services); + } catch (err) { + logger.warn(`${namespace} ${meta.buildName}: Error while updating routes in API, Error: ${err}. Continuing without update`) + } + } + break; + case 'remove': + logger.verbose(`Received remove task for ${namespace}`); + // Update GraphQL API that the Environment has been deleted + try { + await deleteEnvironment(meta.environment, meta.project, false); + logger.info( + `${meta.project}: Deleted Environment '${meta.environment}' in API` + ); + meta.openshiftProject = meta.environment + meta.openshiftProjectName = namespace + meta.projectName = meta.project + sendToLagoonLogs( + 'success', + meta.project, + '', + 'task:remove-kubernetes:finished', + meta, + `*[${meta.project}]* remove \`${meta.environment}\`` + ); + } catch (err) { + logger.warn(`${namespace}: Error while deleting environment, Error: ${err}. Continuing without update`) + } + break; + case 'task': + logger.verbose( + `Received task result for ${meta.task.name} from ${meta.project} - ${meta.environment} - ${meta.jobStatus}` + ); + // if we want to be able to do something else when a task result comes through, + // we can use the task key + switch (meta.key) { + // since the route migration uses the `advanced task` system, we can do something with the data + // that we get back from the controllers + case "kubernetes:route:migrate": + switch (meta.jobStatus) { + case "succeeded": + try { + // get the project ID + const projectResult = await getOpenShiftInfoForProject(meta.project); + const project = projectResult.project + // since the advanceddata contains a base64 encoded value, we have to decode it first + var decodedData = new Buffer(meta.advancedData, 'base64').toString('ascii') + const taskResult = JSON.parse(decodedData) + // the returned data for a route migration is specific to this task, so we use the values contained + // to do something in the api + // in the response, we want to swap these around, so production becomes standby + // standby becomes production + const response = await updateProject(project.id, { + productionEnvironment: taskResult.standbyProductionEnvironment, + standbyProductionEnvironment: taskResult.productionEnvironment, + productionRoutes: taskResult.productionRoutes, + standbyRoutes: taskResult.standbyRoutes, + }); + } catch (err) { + logger.warn(`${namespace}: Error while updating project, Error: ${err}. Continuing without update`) + } + } + break; + } + // since the logging and other stuff is all sent via the controllers directly to message queues + // we only need to update the task here with the status + await updateLagoonTask(meta) + break; + } +}; + +const deathHandler = async (msg, lastError) => { + const { + type, + namespace, + meta, + } = JSON.parse(msg.content.toString()); + + sendToLagoonLogs( + 'error', + meta.project, + '', + 'task:remove-kubernetes:error', //@TODO: this probably needs to be changed to a new event type for the controllers to use? + {}, + `*[${meta.project}]* remove \`${namespace}\` ERROR: +\`\`\` +${lastError} +\`\`\`` + ); +}; + +const retryHandler = async (msg, error, retryCount, retryExpirationSecs) => { + return; +}; + +consumeTasks('controller', messageConsumer, retryHandler, deathHandler); diff --git a/services/controllerhandler/tsconfig.json b/services/controllerhandler/tsconfig.json new file mode 100644 index 0000000000..6ce2574ab8 --- /dev/null +++ b/services/controllerhandler/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist" + }, + "include": ["./src"], + "references": [ + { "path": "../../node-packages/commons" } + ] +} diff --git a/services/kubernetesmisc/src/handlers/ingressMigration.ts b/services/kubernetesmisc/src/handlers/ingressMigration.ts index 21065e5cec..6b874538ee 100644 --- a/services/kubernetesmisc/src/handlers/ingressMigration.ts +++ b/services/kubernetesmisc/src/handlers/ingressMigration.ts @@ -27,17 +27,17 @@ const retry = (retries, fn, delay = 1000) => ); export async function ingressMigration (data) { - const { projectName, productionEnvironment, standbyProductionEnvironment, task } = data; + const { project, productionEnvironment, standbyProductionEnvironment, task } = data; - const result = await getOpenShiftInfoForProject(projectName); + const result = await getOpenShiftInfoForProject(project.name); const projectOpenShift = result.project; const ocsafety = string => string.toLocaleLowerCase().replace(/[^0-9a-z-]/g, '-'); try { - var safeActiveProductionEnvironment = ocsafety(productionEnvironment); - var safeStandbyProductionEnvironment = ocsafety(standbyProductionEnvironment); - var safeProjectName = ocsafety(projectName); + var safeActiveProductionEnvironment = ocsafety(project.productionEnvironment); + var safeStandbyProductionEnvironment = ocsafety(project.standbyProductionEnvironment); + var safeProjectName = ocsafety(project.name); var openshiftConsole = projectOpenShift.openshift.consoleUrl.replace( /\/$/, '' @@ -55,7 +55,7 @@ export async function ingressMigration (data) { .replace('${project}', safeProjectName) : `${safeProjectName}-${safeStandbyProductionEnvironment}`; } catch (error) { - logger.error(`Error while loading information for project ${projectName}`); + logger.error(`Error while loading information for project ${project.name}`); logger.error(error); throw error; } @@ -176,11 +176,11 @@ export async function ingressMigration (data) { sendToLagoonLogs( 'info', - projectName, + project.name, '', 'task:misc-kubernetes:route:migrate', data, - `*[${projectName}]* Ingress Migration between environments *${destinationOpenshiftProject}* started` + `*[${project.name}]* Ingress Migration between environments *${destinationOpenshiftProject}* started` ); const ingressMigrateGet = promisify( @@ -200,7 +200,7 @@ export async function ingressMigration (data) { case 'started': // update the task to started var created = convertDateFormat(ingressMigrateStatus.status.conditions[i].lastTransitionTime) - await updateTask(task.id, { + await updateTask(parseInt(task.id), { status: 'ACTIVE', created: created, }); @@ -208,7 +208,7 @@ export async function ingressMigration (data) { case 'failed': // update the task to failed var created = convertDateFormat(ingressMigrateStatus.status.conditions[i].lastTransitionTime) - await updateTask(task.id, { + await updateTask(parseInt(task.id), { status: 'FAILED', completed: created, }); @@ -238,7 +238,7 @@ export async function ingressMigration (data) { }); // update the task to completed var created = convertDateFormat(ingressMigrateStatus.status.conditions[i].lastTransitionTime) - await updateTask(task.id, { + await updateTask(parseInt(task.id), { status: 'SUCCEEDED', completed: created, }); diff --git a/services/logs2rocketchat/src/readFromRabbitMQ.ts b/services/logs2rocketchat/src/readFromRabbitMQ.ts index 75401b562f..f3a8167397 100644 --- a/services/logs2rocketchat/src/readFromRabbitMQ.ts +++ b/services/logs2rocketchat/src/readFromRabbitMQ.ts @@ -57,7 +57,7 @@ export async function readFromRabbitMQ (msg: ConsumeMessage, channelWrapperLogs: case "gitlab:remove:handled": case "bitbucket:delete:handled": case "api:deleteEnvironment": - text = `*[${meta.projectName}]* deleted in \`${meta.branchName}\`` + text = `*[${meta.projectName}]* delete trigger \`${meta.environmentName}\`` sendToRocketChat(project, text, '#E8E8E8', ':information_source:', channelWrapperLogs, msg, appId) break; @@ -160,6 +160,7 @@ export async function readFromRabbitMQ (msg: ConsumeMessage, channelWrapperLogs: case "task:remove-openshift:error": case "task:remove-kubernetes:error": case "task:remove-openshift-resources:error": + case "task:builddeploy-kubernetes:failed": case "task:builddeploy-openshift:failed": text = `*[${meta.projectName}]*` if (meta.shortSha) { @@ -169,7 +170,7 @@ export async function readFromRabbitMQ (msg: ConsumeMessage, channelWrapperLogs: } text = `${text} Build \`${meta.buildName}\` failed.` if (meta.logLink){ - text = `${text} ${meta.logLink}` + text = `${text} [Logs](${meta.logLink})\n` } sendToRocketChat(project, text, 'red', ':bangbang:', channelWrapperLogs, msg, appId) break; diff --git a/services/openshiftmisc/src/handlers/routeMigration.ts b/services/openshiftmisc/src/handlers/routeMigration.ts index a9c87d59e4..449a511725 100644 --- a/services/openshiftmisc/src/handlers/routeMigration.ts +++ b/services/openshiftmisc/src/handlers/routeMigration.ts @@ -21,17 +21,17 @@ const retry = (retries, fn, delay = 1000) => ); export async function routeMigration (data) { - const { projectName, productionEnvironment, standbyProductionEnvironment, task } = data; + const { project, productionEnvironment, standbyProductionEnvironment, task } = data; - const result = await getOpenShiftInfoForProject(projectName); + const result = await getOpenShiftInfoForProject(project.name); const projectOpenShift = result.project; const ocsafety = string => string.toLocaleLowerCase().replace(/[^0-9a-z-]/g, '-'); try { - var safeActiveProductionEnvironment = ocsafety(productionEnvironment); - var safeStandbyProductionEnvironment = ocsafety(standbyProductionEnvironment); - var safeProjectName = ocsafety(projectName); + var safeActiveProductionEnvironment = ocsafety(project.productionEnvironment); + var safeStandbyProductionEnvironment = ocsafety(project.standbyProductionEnvironment); + var safeProjectName = ocsafety(project.name); var openshiftConsole = projectOpenShift.openshift.consoleUrl.replace( /\/$/, '' @@ -49,7 +49,7 @@ export async function routeMigration (data) { .replace('${project}', safeProjectName) : `${safeProjectName}-${safeStandbyProductionEnvironment}`; } catch (error) { - logger.error(`Error while loading information for project ${projectName}`); + logger.error(`Error while loading information for project ${project.name}`); logger.error(error); throw error; } @@ -169,11 +169,11 @@ export async function routeMigration (data) { sendToLagoonLogs( 'info', - projectName, + project.name, '', 'task:misc-openshift:route:migrate', data, - `*[${projectName}]* Route Migration between environments *${destinationOpenshiftProject}* started` + `*[${project.name}]* Route Migration between environments *${destinationOpenshiftProject}* started` ); const routeMigrateGet = promisify( @@ -193,7 +193,7 @@ export async function routeMigration (data) { case 'started': // update the task to started var created = convertDateFormat(routeMigrateStatus.status.conditions[i].lastTransitionTime) - await updateTask(task.id, { + await updateTask(parseInt(task.id), { status: 'ACTIVE', created: created, }); @@ -201,7 +201,7 @@ export async function routeMigration (data) { case 'failed': // update the task to failed var created = convertDateFormat(routeMigrateStatus.status.conditions[i].lastTransitionTime) - await updateTask(task.id, { + await updateTask(parseInt(task.id), { status: 'FAILED', completed: created, }); @@ -231,7 +231,7 @@ export async function routeMigration (data) { }); // update the task to completed var created = convertDateFormat(routeMigrateStatus.status.conditions[i].lastTransitionTime) - await updateTask(task.id, { + await updateTask(parseInt(task.id), { status: 'SUCCEEDED', completed: created, }); diff --git a/taskimages/README.md b/taskimages/README.md new file mode 100644 index 0000000000..4aaee9209e --- /dev/null +++ b/taskimages/README.md @@ -0,0 +1,4 @@ +# Tasks + +This directory contains images that are used for specific tasks in Lagoon. +These tasks are mainly used when using the Lagoon Kubernetes Controllers \ No newline at end of file diff --git a/taskimages/activestandby/Dockerfile b/taskimages/activestandby/Dockerfile new file mode 100644 index 0000000000..7c914d6b42 --- /dev/null +++ b/taskimages/activestandby/Dockerfile @@ -0,0 +1,26 @@ +# Build the binary +ARG GO_VERSION +FROM golang:${GO_VERSION:-1.13.8} AS builder + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY main.go main.go + +# Build +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o taskrunner main.go + +# Use distroless as minimal base image to package the binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM gcr.io/distroless/static:nonroot +WORKDIR / +COPY --from=builder /workspace/taskrunner . +USER nonroot:nonroot + +ENTRYPOINT ["/taskrunner"] diff --git a/taskimages/activestandby/README.md b/taskimages/activestandby/README.md new file mode 100644 index 0000000000..a1c224088f --- /dev/null +++ b/taskimages/activestandby/README.md @@ -0,0 +1,3 @@ +# tasks-activestandby + +This image is used by the activestandby task when using the Lagoon Kubernetes Controllers \ No newline at end of file diff --git a/taskimages/activestandby/go.mod b/taskimages/activestandby/go.mod new file mode 100644 index 0000000000..2ef64c6507 --- /dev/null +++ b/taskimages/activestandby/go.mod @@ -0,0 +1,10 @@ +module github.com/amazeeio/lagoon/images/tasks/activestandby + +go 1.13 + +require ( + k8s.io/api v0.0.0-20190918155943-95b840bb6a1f + k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655 + k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90 + sigs.k8s.io/controller-runtime v0.4.0 +) diff --git a/taskimages/activestandby/go.sum b/taskimages/activestandby/go.sum new file mode 100644 index 0000000000..bbd45b00c0 --- /dev/null +++ b/taskimages/activestandby/go.sum @@ -0,0 +1,372 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= +github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54= +github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= +github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68= +golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= +gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= +gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.0.0-20190918155943-95b840bb6a1f h1:8FRUST8oUkEI45WYKyD8ed7Ad0Kg5v11zHyPkEVb2xo= +k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48= +k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783 h1:V6ndwCPoao1yZ52agqOKaUAl7DYWVGiXjV7ePA2i610= +k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783/go.mod h1:xvae1SZB3E17UpV59AWc271W/Ph25N+bjPyR63X6tPY= +k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655 h1:CS1tBQz3HOXiseWZu6ZicKX361CZLT97UFnnPx0aqBw= +k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655/go.mod h1:nL6pwRT8NgfF8TT68DBI8uEePRt89cSvoXUVqbkWHq4= +k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad/go.mod h1:XPCXEwhjaFN29a8NldXA901ElnKeKLrLtREO9ZhFyhg= +k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90 h1:mLmhKUm1X+pXu0zXMEzNsOF5E2kKFGe5o6BZBIIqA6A= +k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk= +k8s.io/code-generator v0.0.0-20190912054826-cd179ad6a269/go.mod h1:V5BD6M4CyaN5m+VthcclXWsVcT1Hu+glwa1bi3MIsyE= +k8s.io/component-base v0.0.0-20190918160511-547f6c5d7090/go.mod h1:933PBGtQFJky3TEwYx4aEPZ4IxqhWh3R6DCmzqIn1hA= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.4.0 h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ= +k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE= +k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= +modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= +modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= +modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= +modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= +sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg= +sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns= +sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= +sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH+UQM= +sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/taskimages/activestandby/main.go b/taskimages/activestandby/main.go new file mode 100644 index 0000000000..a622e46500 --- /dev/null +++ b/taskimages/activestandby/main.go @@ -0,0 +1,220 @@ +package main + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "time" + + "gopkg.in/matryer/try.v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// this is the return data structure for the active standby task. +// this will be sent back to lagoon as a payload to be processed. +type returnData struct { + Status string `json:"status"` + ProductionEnvironment string `json:"productionEnvironment"` + StandbyProdutionEnvironment string `json:"standbyProductionEnvironment"` + ProductionRoutes string `json:"productionRoutes"` + StandbyRoutes string `json:"standbyRoutes"` +} + +func main() { + // get the values from the provided environment variables. + JSONPayload := os.Getenv("JSON_PAYLOAD") + podName := os.Getenv("PODNAME") + podNamespace := os.Getenv("NAMESPACE") + // check that they aren't empty. + if JSONPayload == "" { + fmt.Printf("Task failed, error was: no payload provided") + os.Exit(1) + } + if podName == "" { + fmt.Printf("Task failed, error was: no podname provided") + os.Exit(1) + } + if podNamespace == "" { + fmt.Printf("Task failed, error was: no podnamespace provided") + os.Exit(1) + } + + // read the deployer token. + token, err := ioutil.ReadFile("/var/run/secrets/lagoon/deployer/token") + if err != nil { + fmt.Printf("Task failed to read the token, error was: %v", err) + os.Exit(1) + } + // generate the rest config for the client. + config := &rest.Config{ + BearerToken: string(token), + Host: "https://kubernetes.default.svc", + TLSClientConfig: rest.TLSClientConfig{ + Insecure: true, + }, + } + // create the client using the rest config. + c, err := client.New(config, client.Options{}) + if err != nil { + fmt.Printf("Task failed creating the client, error was: %v", err) + os.Exit(1) + } + + // decode the payload data and unmarshal it. + payloadBytes, err := base64.StdEncoding.DecodeString(JSONPayload) + if err != nil { + fmt.Printf("Task failed to decode the supplied payload data, error was: %v", err) + os.Exit(1) + } + var payloadData map[string]interface{} + if err := json.Unmarshal(payloadBytes, &payloadData); err != nil { + fmt.Printf("Task failed to unsmarshal the given payload data, error was: %v", err) + os.Exit(1) + } + + // get the provided CRD from the payload data and unmarshal it to unstructured so we can create it in kubernetes. + crdBytes, err := json.Marshal(payloadData["crd"]) + if err != nil { + fmt.Printf("Task failed to marshal the given payload data, error was: %v", err) + os.Exit(1) + } + crd := unstructured.Unstructured{} + if err := crd.UnmarshalJSON([]byte(crdBytes)); err != nil { + fmt.Printf("Task failed to unsmarshal the given payload data, error was: %v", err) + os.Exit(1) + } + // set the namespace for the crd. + crd.SetNamespace(podNamespace) + + // create the crd in kubernetes. + if err := c.Create(context.Background(), &crd); err != nil { + fmt.Printf("Task failed to create the object, error was: %v", err) + os.Exit(1) + } + + // check the status of the crd until we have the status conditions. + // otherwise give up after a few minutes. + err = try.Do(func(attempt int) (bool, error) { + var err error + if err := c.Get(context.Background(), types.NamespacedName{ + Namespace: podNamespace, + Name: crd.GetName(), + }, &crd); err != nil { + fmt.Printf("Task failed to get the object from kubernetes, error was: %v", err) + os.Exit(1) + } + // check if the status exists, the job may not have started. + if _, ok := crd.Object["status"]; ok { + conditions := crd.Object["status"].(map[string]interface{}) + // check if the conditions exists, the job may not have started. + if _, ok := conditions["conditions"]; ok { + // loop over the conditions until we get a completed or failed status. + for _, condition := range conditions["conditions"].([]interface{}) { + mapval := condition.(map[string]interface{}) + // if the status is failed, we need to make sure the pod exits accordingly + if mapval["type"].(string) == "failed" { + crdSpec := crd.Object["spec"].(map[string]interface{}) + if crdSpec != nil { + crdIngress := crdSpec["ingress"].(map[string]interface{}) + if crdIngress != nil { + rData := returnData{ + Status: "Failed", + ProductionEnvironment: payloadData["productionEnvironment"].(string), + StandbyProdutionEnvironment: payloadData["standbyEnvironment"].(string), + ProductionRoutes: crdIngress["activeIngress"].(string), + StandbyRoutes: crdIngress["standbyIngress"].(string), + } + + // print the result of the task, it will go back to lagoon-logs to be displayed + // to the user + jsonData, _ := json.Marshal(rData) + fmt.Println(string(jsonData)) + // exit as the task failed + os.Exit(1) + } + fmt.Printf("Task failed, error was: no ingress found in resource") + os.Exit(1) + } + fmt.Printf("Task failed, error was: no spec found in resource") + os.Exit(1) + } + // if the status is completed, then do some additional steps as there could still be a failure + if mapval["type"].(string) == "completed" { + crdSpec := crd.Object["spec"].(map[string]interface{}) + if crdSpec != nil { + crdIngress := crdSpec["ingress"].(map[string]interface{}) + if crdIngress != nil { + rData := returnData{ + Status: "Completed", + ProductionEnvironment: payloadData["productionEnvironment"].(string), + StandbyProdutionEnvironment: payloadData["standbyEnvironment"].(string), + ProductionRoutes: crdIngress["activeIngress"].(string), + StandbyRoutes: crdIngress["standbyIngress"].(string), + } + + // print the result of the task, it will go back to lagoon-logs to be displayed + // to the user + jsonData, _ := json.Marshal(rData) + fmt.Println(string(jsonData)) + + // update this pods annotations so that the lagoonmonitor controller + // knows that it needs to send information back to lagoon + pod := corev1.Pod{} + if err := c.Get(context.Background(), types.NamespacedName{ + Namespace: podNamespace, + Name: podName, + }, &pod); err != nil { + fmt.Printf(`======================================== +Task failed to get the pod to update, error was: %v +======================================== +The active standby switch completed, but Lagoon has not been updated to reflect the changes. +Please contact your Lagoon administrator to make sure your project gets updated correctly. +Provide a copy of this entire log to the team.`, err) + os.Exit(1) + } + // the job data to send back to lagoon must be base64 encoded + pod.ObjectMeta.Annotations = map[string]string{ + "lagoon.sh/taskData": base64.StdEncoding.EncodeToString(jsonData), + } + // update the pod with the annotation + if err := c.Update(context.Background(), &pod); err != nil { + fmt.Printf(`======================================== +Task failed to update pod with return information, error was: %v +======================================== +The active standby switch completed, but Lagoon has not been updated to reflect the changes. +Please contact your Lagoon administrator to make sure your project gets updated correctly. +Provide a copy of this entire log to the team.`, err) + // if the update fails, exit 1 + // if this update fails, it will not update the annotation on the pod + // and so the monitor controller won't know to send the response data to lagoon + // in this case, the migration completed, but the task failed + // inform the user + os.Exit(1) + } + os.Exit(0) + } + fmt.Printf("Task failed, error was: no ingress found in resource") + os.Exit(1) + } + fmt.Printf("Task failed, error was: no spec found in resource") + os.Exit(1) + } + } + } + } + // sleep for 5 seconds up to a maximum of 60 times (5 minutes) before finally giving up + time.Sleep(5 * time.Second) + return attempt < 60, err + }) + if err != nil { + fmt.Printf("Task failed, timed out waiting for the job to start: %v", err) + os.Exit(1) + } +} diff --git a/tests/files/features/.lagoon.yml b/tests/files/features/.lagoon.yml index 31d34bde67..65f8a0771e 100644 --- a/tests/files/features/.lagoon.yml +++ b/tests/files/features/.lagoon.yml @@ -87,6 +87,19 @@ ci-multiproject1-kubernetes: - node: - multiproject1.com ci-multiproject2-kubernetes: + environments: + multiproject: + routes: + - node: + - multiproject2.com + +ci-multiproject1-control-k8s: + environments: + multiproject: + routes: + - node: + - multiproject1.com +ci-multiproject2-control-k8s: environments: multiproject: routes: diff --git a/tests/tests/active-standby-kubernetes.yaml b/tests/tests/active-standby-kubernetes.yaml index c161f35f12..8744e3e42a 100644 --- a/tests/tests/active-standby-kubernetes.yaml +++ b/tests/tests/active-standby-kubernetes.yaml @@ -8,7 +8,7 @@ vars: testname: "ACTIVE_STANDBY" git_repo_name: active-standby.git - project: ci-active-standby-k8s + project: ci-active-standby-{{ lookup('env','CLUSTER_TYPE') }} branch: master-a standby_branch: master-b error_code_check: 404 \ No newline at end of file diff --git a/tests/tests/active-standby-openshift.yaml b/tests/tests/active-standby-openshift.yaml index 612aa65665..ee121caf3e 100644 --- a/tests/tests/active-standby-openshift.yaml +++ b/tests/tests/active-standby-openshift.yaml @@ -8,7 +8,7 @@ vars: testname: "ACTIVE_STANDBY" git_repo_name: active-standby.git - project: ci-active-standby + project: ci-active-standby-{{ lookup('env','CLUSTER_TYPE') }} branch: master-a standby_branch: master-b error_code_check: 503 \ No newline at end of file diff --git a/tests/tests/active-standby/deploy-active-standby.yaml b/tests/tests/active-standby/deploy-active-standby.yaml index 593a050d44..f7cc1aca48 100644 --- a/tests/tests/active-standby/deploy-active-standby.yaml +++ b/tests/tests/active-standby/deploy-active-standby.yaml @@ -8,25 +8,25 @@ headers: Authorization: "Bearer {{ token }}" body_format: json - body: '{ "query": "mutation($projectName: String!) {switchActiveStandby(input:{project:{name:$projectName}}){id, remoteId}}", "variables": {"projectName":"{{ project }}"}}' + body: '{ "query": "mutation($projectName: String!) {switchActiveStandby(input:{project:{name:$projectName}}){id}}", "variables": {"projectName":"{{ project }}"}}' register: apiresponse until: - name: "{{ testname }} - POST api switchActiveStandby with target project {{ project }} (no sha) to {{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" debug: msg: "api response: {{ apiresponse.json }}" - - name: "{{ testname }} - POST api taskByRemoteId with remoteID {{ apiresponse.json.data.switchActiveStandby.remoteId }} for migration status to {{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" + - name: "{{ testname }} - POST api taskById with ID {{ apiresponse.json.data.switchActiveStandby.id }} for migration status to {{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" uri: url: "{{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" method: POST headers: Authorization: "Bearer {{ token }}" body_format: json - body: '{ "query": "query($remoteId: String!) {taskByRemoteId(id: $remoteId){status}}", "variables": {"remoteId":"{{ apiresponse.json.data.switchActiveStandby.remoteId }}"}}' + body: '{ "query": "query($id: Int!) {taskById(id: $id){status}}", "variables": {"id":{{ apiresponse.json.data.switchActiveStandby.id }}}}' register: taskresult - until: taskresult.json.data.taskByRemoteId.status == "succeeded" or taskresult.json.data.taskByRemoteId.status == "failed" + until: taskresult.json.data.taskById.status == "succeeded" or taskresult.json.data.taskById.status == "failed" retries: 10 delay: 5 - name: "{{ testname }} - fail if task fails" fail: msg: "The route migration failed for some reason" - when: taskresult.json.data.taskByRemoteId.status == "failed" \ No newline at end of file + when: taskresult.json.data.taskById.status == "failed" \ No newline at end of file diff --git a/tests/tests/active-standby/remove.yaml b/tests/tests/active-standby/remove.yaml index db568fbfc0..ffcbbcc99f 100644 --- a/tests/tests/active-standby/remove.yaml +++ b/tests/tests/active-standby/remove.yaml @@ -13,3 +13,27 @@ - name: "{{ testname }} - POST api deleteEnvironment with project {{ project }} and branch {{ standby_branch }} to {{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" debug: msg: "api response: {{ apiresponse.json }}" + - name: "{{ testname }} - POST api get project id {{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" + uri: + url: "{{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" + method: POST + headers: + Authorization: "Bearer {{ token }}" + body_format: json + body: '{ "query": "query($projectName: String!) {projectByName(name:$projectName){id}}", "variables": {"projectName":"{{ project }}"}}' + register: apiresponse + - name: "{{ testname }} - POST api get project id {{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" + debug: + msg: "api response: {{ apiresponse.json }}" + - name: "{{ testname }} - POST api updateProject {{ apiresponse.json.data.projectByName.id }} to reset production and standby {{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" + uri: + url: "{{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" + method: POST + headers: + Authorization: "Bearer {{ token }}" + body_format: json + body: '{ "query": "mutation($projectId: Int!) {updateProject(input:{id:$projectId,patch:{productionEnvironment:\"master-a\",standbyProductionEnvironment:\"master-b\"}}){name,productionEnvironment,standbyProductionEnvironment}}","variables": {"projectId":{{ apiresponse.json.data.projectByName.id }}}}' + register: apiresponse + - name: "{{ testname }} - POST api updateProject to reset production and standby {{ lookup('env','API_PROTOCOL') }}://{{ lookup('env','API_HOST') }}:{{ lookup('env','API_PORT') }}/graphql" + debug: + msg: "api response: {{ apiresponse.json }}" \ No newline at end of file