From 01aa1ef77beee21a588f8b6b27bd372fc7ed7c8d Mon Sep 17 00:00:00 2001 From: James Fargher Date: Thu, 21 Mar 2019 08:06:47 +0000 Subject: Update dashboards to additionally use new environment selector Deploy boards now will check for app.gitlab.com/env and app.gitlab.com/app --- app/models/clusters/platforms/kubernetes.rb | 2 +- app/models/project_services/kubernetes_service.rb | 4 +-- .../unreleased/k8s_new_deployment_labels.yml | 5 ++++ lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml | 4 +++ lib/gitlab/kubernetes.rb | 24 +++++++++++++++ spec/lib/gitlab/kubernetes_spec.rb | 34 ++++++++++++++++++++-- spec/models/clusters/platforms/kubernetes_spec.rb | 6 ++-- .../project_services/kubernetes_service_spec.rb | 5 ++-- spec/support/helpers/kubernetes_helpers.rb | 16 ++++++---- 9 files changed, 85 insertions(+), 15 deletions(-) create mode 100644 changelogs/unreleased/k8s_new_deployment_labels.yml diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb index fb2221b601f..7786b48429c 100644 --- a/app/models/clusters/platforms/kubernetes.rb +++ b/app/models/clusters/platforms/kubernetes.rb @@ -110,7 +110,7 @@ module Clusters # short time later def terminals(environment) with_reactive_cache do |data| - pods = filter_by_label(data[:pods], app: environment.slug) + pods = filter_by_project_environment(data[:pods], project.full_path_slug, environment.slug) terminals = pods.flat_map { |pod| terminals_for_pod(api_url, actual_namespace, pod) }.compact terminals.each { |terminal| add_terminal_auth(terminal, terminal_auth) } end diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb index 4cf3a7f3d84..f650dbd3726 100644 --- a/app/models/project_services/kubernetes_service.rb +++ b/app/models/project_services/kubernetes_service.rb @@ -131,8 +131,8 @@ class KubernetesService < DeploymentService # short time later def terminals(environment) with_reactive_cache do |data| - pods = filter_by_label(data[:pods], app: environment.slug) - terminals = pods.flat_map { |pod| terminals_for_pod(api_url, actual_namespace, pod) } + pods = filter_by_project_environment(data[:pods], project.full_path_slug, environment.slug) + terminals = pods.flat_map { |pod| terminals_for_pod(api_url, actual_namespace, pod) }.compact terminals.each { |terminal| add_terminal_auth(terminal, terminal_auth) } end end diff --git a/changelogs/unreleased/k8s_new_deployment_labels.yml b/changelogs/unreleased/k8s_new_deployment_labels.yml new file mode 100644 index 00000000000..e9ef3ee0082 --- /dev/null +++ b/changelogs/unreleased/k8s_new_deployment_labels.yml @@ -0,0 +1,5 @@ +--- +title: Update deploy boards to additionally select on "app.gitlab.com" annotations +merge_request: 25623 +author: +type: changed diff --git a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml index cbe466a1c37..7ec786b6d5d 100644 --- a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml @@ -697,6 +697,8 @@ rollout 100%: helm upgrade --install \ --wait \ --set service.enabled="$service_enabled" \ + --set gitlab.app="$CI_PROJECT_PATH_SLUG" \ + --set gitlab.env="$CI_ENVIRONMENT_SLUG" \ --set releaseOverride="$CI_ENVIRONMENT_SLUG" \ --set image.repository="$CI_APPLICATION_REPOSITORY" \ --set image.tag="$CI_APPLICATION_TAG" \ @@ -734,6 +736,8 @@ rollout 100%: helm upgrade --install \ --wait \ --set service.enabled="$service_enabled" \ + --set gitlab.app="$CI_PROJECT_PATH_SLUG" \ + --set gitlab.env="$CI_ENVIRONMENT_SLUG" \ --set releaseOverride="$CI_ENVIRONMENT_SLUG" \ --set image.repository="$CI_APPLICATION_REPOSITORY" \ --set image.tag="$CI_APPLICATION_TAG" \ diff --git a/lib/gitlab/kubernetes.rb b/lib/gitlab/kubernetes.rb index a9957a85d48..d46b5e3aee3 100644 --- a/lib/gitlab/kubernetes.rb +++ b/lib/gitlab/kubernetes.rb @@ -24,6 +24,30 @@ module Gitlab end end + # Filters an array of pods (as returned by the kubernetes API) by their annotations + def filter_by_annotation(items, annotations = {}) + items.select do |item| + metadata = item.fetch("metadata", {}) + item_annotations = metadata.fetch("annotations", nil) + next unless item_annotations + + annotations.all? { |k, v| item_annotations[k.to_s] == v } + end + end + + # Filters an array of pods (as returned by the kubernetes API) by their project and environment + def filter_by_project_environment(items, app, env) + pods = filter_by_annotation(items, { + 'app.gitlab.com/app' => app, + 'app.gitlab.com/env' => env + }) + return pods unless pods.empty? + + filter_by_label(items, { + 'app' => env, # deprecated: replaced by app.gitlab.com/env + }) + end + # Converts a pod (as returned by the kubernetes API) into a terminal def terminals_for_pod(api_url, namespace, pod) metadata = pod.fetch("metadata", {}) diff --git a/spec/lib/gitlab/kubernetes_spec.rb b/spec/lib/gitlab/kubernetes_spec.rb index f326d57e9c6..57b570a9166 100644 --- a/spec/lib/gitlab/kubernetes_spec.rb +++ b/spec/lib/gitlab/kubernetes_spec.rb @@ -40,10 +40,40 @@ describe Gitlab::Kubernetes do describe '#filter_by_label' do it 'returns matching labels' do - matching_items = [kube_pod(app: 'foo')] + matching_items = [kube_pod(track: 'foo'), kube_deployment(track: 'foo')] + items = matching_items + [kube_pod, kube_deployment] + + expect(filter_by_label(items, 'track' => 'foo')).to eq(matching_items) + end + end + + describe '#filter_by_annotation' do + it 'returns matching labels' do + matching_items = [kube_pod(environment_slug: 'foo'), kube_deployment(environment_slug: 'foo')] + items = matching_items + [kube_pod, kube_deployment] + + expect(filter_by_annotation(items, 'app.gitlab.com/env' => 'foo')).to eq(matching_items) + end + end + + describe '#filter_by_project_environment' do + let(:matching_pod) { kube_pod(environment_slug: 'production', project_slug: 'my-cool-app') } + + it 'returns matching legacy env label' do + matching_pod['metadata']['annotations'].delete('app.gitlab.com/app') + matching_pod['metadata']['annotations'].delete('app.gitlab.com/env') + matching_pod['metadata']['labels']['app'] = 'production' + matching_items = [matching_pod] + items = matching_items + [kube_pod] + + expect(filter_by_project_environment(items, 'my-cool-app', 'production')).to eq(matching_items) + end + + it 'returns matching env label' do + matching_items = [matching_pod] items = matching_items + [kube_pod] - expect(filter_by_label(items, app: 'foo')).to eq(matching_items) + expect(filter_by_project_environment(items, 'my-cool-app', 'production')).to eq(matching_items) end end diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index cc93a1b4965..af65530e663 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -375,14 +375,14 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching end context 'with valid pods' do - let(:pod) { kube_pod(app: environment.slug) } - let(:pod_with_no_terminal) { kube_pod(app: environment.slug, status: "Pending") } + let(:pod) { kube_pod(environment_slug: environment.slug, project_slug: project.full_path_slug) } + let(:pod_with_no_terminal) { kube_pod(environment_slug: environment.slug, project_slug: project.full_path_slug, status: "Pending") } let(:terminals) { kube_terminals(service, pod) } before do stub_reactive_cache( service, - pods: [pod, pod, pod_with_no_terminal, kube_pod(app: "should-be-filtered-out")] + pods: [pod, pod, pod_with_no_terminal, kube_pod(environment_slug: "should-be-filtered-out")] ) end diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index cb20c747972..56e587262ef 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -323,13 +323,14 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do end context 'with valid pods' do - let(:pod) { kube_pod(app: environment.slug) } + let(:pod) { kube_pod(environment_slug: environment.slug, project_slug: project.full_path_slug) } + let(:pod_with_no_terminal) { kube_pod(environment_slug: environment.slug, project_slug: project.full_path_slug, status: "Pending") } let(:terminals) { kube_terminals(service, pod) } before do stub_reactive_cache( service, - pods: [pod, pod, kube_pod(app: "should-be-filtered-out")] + pods: [pod, pod, pod_with_no_terminal, kube_pod(environment_slug: "should-be-filtered-out")] ) end diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb index cca11e112c9..ac52acb6570 100644 --- a/spec/support/helpers/kubernetes_helpers.rb +++ b/spec/support/helpers/kubernetes_helpers.rb @@ -250,16 +250,19 @@ module KubernetesHelpers # This is a partial response, it will have many more elements in reality but # these are the ones we care about at the moment - def kube_pod(name: "kube-pod", app: "valid-pod-label", status: "Running", track: nil) + def kube_pod(name: "kube-pod", environment_slug: "production", project_slug: "project-path-slug", status: "Running", track: nil) { "metadata" => { "name" => name, "generate_name" => "generated-name-with-suffix", "creationTimestamp" => "2016-11-25T19:55:19Z", + "annotations" => { + "app.gitlab.com/env" => environment_slug, + "app.gitlab.com/app" => project_slug + }, "labels" => { - "app" => app, "track" => track - } + }.compact }, "spec" => { "containers" => [ @@ -293,13 +296,16 @@ module KubernetesHelpers } end - def kube_deployment(name: "kube-deployment", app: "valid-deployment-label", track: nil) + def kube_deployment(name: "kube-deployment", environment_slug: "production", project_slug: "project-path-slug", track: nil) { "metadata" => { "name" => name, "generation" => 4, + "annotations" => { + "app.gitlab.com/env" => environment_slug, + "app.gitlab.com/app" => project_slug + }, "labels" => { - "app" => app, "track" => track }.compact }, -- cgit v1.2.1