Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gcloud.rb « cluster_provider « service « qa « qa - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7993cf4ab4dfc6f1709379f3a2dd5d5caa9c229c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# frozen_string_literal: true

require 'active_support/inflector'

module QA
  module Service
    module ClusterProvider
      class Gcloud < Base
        def validate_dependencies
          find_executable('gcloud') || raise("You must first install `gcloud` executable to run these tests.")
        end

        def initialize(rbac:)
          super(rbac: rbac)
          @attempts = 0
          @available_regions = %w(
            asia-east1 asia-east2
            asia-northeast1 asia-south1
            asia-southeast1 australia-southeast1
            europe-west1 europe-west2 europe-west4
            northamerica-northeast1 southamerica-east1
            us-central1 us-east1 us-east4
            us-west1 us-west2
          )
        end

        def setup
          login_if_not_already_logged_in
          create_cluster
          install_helm
        end

        def teardown
          delete_cluster
        end

        def connect
          login_if_not_already_logged_in

          shell <<~CMD.tr("\n", ' ')
            gcloud container clusters get-credentials
              --region #{Runtime::Env.workspaces_cluster_region}
              #{Runtime::Env.workspaces_cluster_name}
          CMD
        end

        def install_kubernetes_agent(agent_token:, kas_address:, agent_name: "gitlab-agent")
          cmd_str = <<~CMD.tr("\n", ' ')
            helm repo add gitlab https://charts.gitlab.io &&
            helm repo update &&
            helm upgrade --install gitlab-agent gitlab/gitlab-agent
              --namespace "#{agent_name}"
              --create-namespace
              --set image.tag=#{Runtime::Env.gitlab_agentk_version}
              --set config.token=#{agent_token}
              --set config.kasAddress=#{kas_address}
              --set config.kasHeaders="{Cookie: gitlab_canary=#{target_canary?}}"
          CMD
          shell(cmd_str, mask_secrets: [agent_token])
        end

        def uninstall_kubernetes_agent(agent_name: "gitlab-agent")
          shell <<~CMD.tr("\n", ' ')
            helm uninstall gitlab-agent \
              --namespace "#{agent_name}"
          CMD
        end

        def install_ngnix_ingress
          shell <<~CMD.tr("\n", ' ')
            helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx &&
            helm repo update &&
            helm install \
              ingress-nginx ingress-nginx/ingress-nginx \
              --namespace ingress-nginx \
              --create-namespace \
              --version 4.3.0
          CMD
        end

        def install_gitlab_workspaces_proxy
          cmd_str = <<~CMD.tr("\n", ' ')
            helm repo add gitlab-workspaces-proxy \
              https://gitlab.com/api/v4/projects/gitlab-org%2fremote-development%2fgitlab-workspaces-proxy/packages/helm/devel &&
            helm repo update &&
            helm upgrade --install gitlab-workspaces-proxy \
              gitlab-workspaces-proxy/gitlab-workspaces-proxy \
              --version 0.1.6 \
              --namespace=gitlab-workspaces \
              --create-namespace \
              --set="auth.client_id=#{Runtime::Env.workspaces_oauth_app_id}" \
              --set="auth.client_secret=#{Runtime::Env.workspaces_oauth_app_secret}" \
              --set="auth.host=#{Runtime::Env.gitlab_url}" \
              --set="auth.redirect_uri=https://#{Runtime::Env.workspaces_proxy_domain}/auth/callback" \
              --set="auth.signing_key=#{Runtime::Env.workspaces_oauth_signing_key}" \
              --set="ingress.host.workspaceDomain=#{Runtime::Env.workspaces_proxy_domain}" \
              --set="ingress.host.wildcardDomain=*.#{Runtime::Env.workspaces_proxy_domain}" \
              --set="ingress.tls.workspaceDomainCert=$(cat #{Runtime::Env.workspaces_domain_cert})" \
              --set="ingress.tls.workspaceDomainKey=$(cat #{Runtime::Env.workspaces_domain_key})" \
              --set="ingress.tls.wildcardDomainCert=$(cat #{Runtime::Env.workspaces_wildcard_cert})" \
              --set="ingress.tls.wildcardDomainKey=$(cat #{Runtime::Env.workspaces_wildcard_key})" \
              --set="ingress.className=nginx"
          CMD

          shell(cmd_str, mask_secrets: [Runtime::Env.workspaces_oauth_app_secret, Runtime::Env.workspaces_oauth_signing_key])
        end

        def update_dns(load_balancer_ip)
          shell <<~CMD.tr("\n", ' ')
            gcloud dns record-sets update #{Runtime::Env.workspaces_proxy_domain} \
            --rrdatas=#{load_balancer_ip} \
            --ttl=300 \
            --type=A \
            --zone=gitlabqa-dev
          CMD

          shell <<~CMD.tr("\n", ' ')
            gcloud dns record-sets update "*.#{Runtime::Env.workspaces_proxy_domain}" \
            --rrdatas=#{load_balancer_ip} \
            --ttl=300 \
            --type=A \
            --zone=gitlabqa-dev
          CMD
        end

        private

        def install_helm
          shell <<~CMD.tr("\n", ' ')
            curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 &&
            chmod 700 get_helm.sh &&
            DESIRED_VERSION=v3.7.0 ./get_helm.sh
          CMD
        end

        def target_canary?
          Runtime::Env.qa_cookies.to_s.include?("gitlab_canary=true")
        end

        def login_if_not_already_logged_in
          if Runtime::Env.has_gcloud_credentials?
            attempt_login_with_env_vars
          else
            account = `gcloud auth list --filter=status:ACTIVE --format="value(account)"`
            if account.empty?
              raise "Failed to login to gcloud. No credentials provided in environment and no credentials found locally."
            else
              QA::Runtime::Logger.debug("gcloud account found. Using: #{account} for creating K8s cluster.")
            end
          end
        end

        def attempt_login_with_env_vars
          QA::Runtime::Logger.debug("Logging in with GCLOUD_ACCOUNT_EMAIL and GCLOUD_ACCOUNT_KEY.")
          gcloud_account_key = Tempfile.new('gcloud-account-key')
          gcloud_account_key.write(Runtime::Env.gcloud_account_key)
          gcloud_account_key.close
          gcloud_account_email = Runtime::Env.gcloud_account_email
          shell("gcloud auth activate-service-account #{gcloud_account_email} --key-file #{gcloud_account_key.path}")
        ensure
          gcloud_account_key && gcloud_account_key.unlink
        end

        def auth_options
          "--enable-legacy-authorization" unless rbac
        end

        def create_cluster
          @region = get_region

          shell <<~CMD.tr("\n", ' ')
            gcloud container clusters
            create #{cluster_name}
            #{auth_options}
            --region #{@region}
            --disk-size 15GB
            --num-nodes #{Runtime::Env.gcloud_num_nodes}
            && gcloud container clusters
            get-credentials
            --region #{@region}
            #{cluster_name}
          CMD
        rescue QA::Service::Shellout::CommandError
          @attempts += 1

          retry unless @attempts > 1

          raise $!, "Tried and failed to provision the cluster #{@attempts} #{"time".pluralize(@attempts)}.", $!.backtrace
        end

        def delete_cluster
          shell <<~CMD.tr("\n", ' ')
            gcloud container clusters delete
              --region #{@region}
              #{cluster_name}
              --quiet --async
          CMD
        end

        def get_region
          Runtime::Env.gcloud_region || @available_regions.delete(@available_regions.sample)
        end
      end
    end
  end
end