summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzciński <ayufan@ayufan.eu>2017-07-06 13:05:50 +0000
committerKamil Trzciński <ayufan@ayufan.eu>2017-07-06 13:05:50 +0000
commite0b3257b36396a43495a148b7642435c6cae82a5 (patch)
treebdee0e945bcacf24709daaf7299375dd359621cc
parenta33fb2132cc9c1924fe986ce562cd7bea084a5c9 (diff)
parentdbb313c26f79e5bebf197af8eba24411fced51bb (diff)
downloadgitlab-ce-e0b3257b36396a43495a148b7642435c6cae82a5.tar.gz
Merge branch '33360-generate-kubeconfig' into 'master'
Generate KUBECONFIG in KubernetesService#predefined_variables Closes #33360 See merge request !12223
-rw-r--r--app/models/project_services/kubernetes_service.rb13
-rw-r--r--changelogs/unreleased/33360-generate-kubeconfig.yml4
-rw-r--r--doc/user/project/integrations/kubernetes.md1
-rw-r--r--lib/gitlab/kubernetes.rb39
-rw-r--r--spec/fixtures/config/kubeconfig-without-ca.yml18
-rw-r--r--spec/fixtures/config/kubeconfig.yml19
-rw-r--r--spec/lib/gitlab/kubernetes_spec.rb24
-rw-r--r--spec/models/project_services/kubernetes_service_spec.rb48
8 files changed, 150 insertions, 16 deletions
diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb
index 48e7802c557..62f7c057c5b 100644
--- a/app/models/project_services/kubernetes_service.rb
+++ b/app/models/project_services/kubernetes_service.rb
@@ -96,10 +96,13 @@ class KubernetesService < DeploymentService
end
def predefined_variables
+ config = YAML.dump(kubeconfig)
+
variables = [
{ key: 'KUBE_URL', value: api_url, public: true },
{ key: 'KUBE_TOKEN', value: token, public: false },
- { key: 'KUBE_NAMESPACE', value: actual_namespace, public: true }
+ { key: 'KUBE_NAMESPACE', value: actual_namespace, public: true },
+ { key: 'KUBECONFIG', value: config, public: false, file: true }
]
if ca_pem.present?
@@ -135,6 +138,14 @@ class KubernetesService < DeploymentService
private
+ def kubeconfig
+ to_kubeconfig(
+ url: api_url,
+ namespace: actual_namespace,
+ token: token,
+ ca_pem: ca_pem)
+ end
+
def namespace_placeholder
default_namespace || TEMPLATE_PLACEHOLDER
end
diff --git a/changelogs/unreleased/33360-generate-kubeconfig.yml b/changelogs/unreleased/33360-generate-kubeconfig.yml
new file mode 100644
index 00000000000..96f0b1bc93f
--- /dev/null
+++ b/changelogs/unreleased/33360-generate-kubeconfig.yml
@@ -0,0 +1,4 @@
+---
+title: Provide KUBECONFIG from KubernetesService for runners
+merge_request: 12223
+author:
diff --git a/doc/user/project/integrations/kubernetes.md b/doc/user/project/integrations/kubernetes.md
index 73fa83d72a8..bfe2672e098 100644
--- a/doc/user/project/integrations/kubernetes.md
+++ b/doc/user/project/integrations/kubernetes.md
@@ -55,6 +55,7 @@ GitLab CI build environment:
- `KUBE_CA_PEM_FILE` - only present if a custom CA bundle was specified. Path
to a file containing PEM data.
- `KUBE_CA_PEM` (deprecated)- only if a custom CA bundle was specified. Raw PEM data.
+- `KUBECONFIG` - Path to a file containing kubeconfig for this deployment. CA bundle would be embedded if specified.
## Web terminals
diff --git a/lib/gitlab/kubernetes.rb b/lib/gitlab/kubernetes.rb
index c56c1a4322f..cdbdfa10d0e 100644
--- a/lib/gitlab/kubernetes.rb
+++ b/lib/gitlab/kubernetes.rb
@@ -76,5 +76,44 @@ module Gitlab
url.to_s
end
+
+ def to_kubeconfig(url:, namespace:, token:, ca_pem: nil)
+ config = {
+ apiVersion: 'v1',
+ clusters: [
+ name: 'gitlab-deploy',
+ cluster: {
+ server: url
+ }
+ ],
+ contexts: [
+ name: 'gitlab-deploy',
+ context: {
+ cluster: 'gitlab-deploy',
+ namespace: namespace,
+ user: 'gitlab-deploy'
+ }
+ ],
+ 'current-context': 'gitlab-deploy',
+ kind: 'Config',
+ users: [
+ {
+ name: 'gitlab-deploy',
+ user: { token: token }
+ }
+ ]
+ }
+
+ kubeconfig_embed_ca_pem(config, ca_pem) if ca_pem
+
+ config.deep_stringify_keys
+ end
+
+ private
+
+ def kubeconfig_embed_ca_pem(config, ca_pem)
+ cluster = config.dig(:clusters, 0, :cluster)
+ cluster[:'certificate-authority-data'] = Base64.encode64(ca_pem)
+ end
end
end
diff --git a/spec/fixtures/config/kubeconfig-without-ca.yml b/spec/fixtures/config/kubeconfig-without-ca.yml
new file mode 100644
index 00000000000..b2cb989d548
--- /dev/null
+++ b/spec/fixtures/config/kubeconfig-without-ca.yml
@@ -0,0 +1,18 @@
+---
+apiVersion: v1
+clusters:
+- name: gitlab-deploy
+ cluster:
+ server: https://kube.domain.com
+contexts:
+- name: gitlab-deploy
+ context:
+ cluster: gitlab-deploy
+ namespace: NAMESPACE
+ user: gitlab-deploy
+current-context: gitlab-deploy
+kind: Config
+users:
+- name: gitlab-deploy
+ user:
+ token: TOKEN
diff --git a/spec/fixtures/config/kubeconfig.yml b/spec/fixtures/config/kubeconfig.yml
new file mode 100644
index 00000000000..c4e8e573c32
--- /dev/null
+++ b/spec/fixtures/config/kubeconfig.yml
@@ -0,0 +1,19 @@
+---
+apiVersion: v1
+clusters:
+- name: gitlab-deploy
+ cluster:
+ server: https://kube.domain.com
+ certificate-authority-data: "UEVN\n"
+contexts:
+- name: gitlab-deploy
+ context:
+ cluster: gitlab-deploy
+ namespace: NAMESPACE
+ user: gitlab-deploy
+current-context: gitlab-deploy
+kind: Config
+users:
+- name: gitlab-deploy
+ user:
+ token: TOKEN
diff --git a/spec/lib/gitlab/kubernetes_spec.rb b/spec/lib/gitlab/kubernetes_spec.rb
index e8c599a95ee..34b33772578 100644
--- a/spec/lib/gitlab/kubernetes_spec.rb
+++ b/spec/lib/gitlab/kubernetes_spec.rb
@@ -46,4 +46,28 @@ describe Gitlab::Kubernetes do
expect(filter_by_label(items, app: 'foo')).to eq(matching_items)
end
end
+
+ describe '#to_kubeconfig' do
+ subject do
+ to_kubeconfig(
+ url: 'https://kube.domain.com',
+ namespace: 'NAMESPACE',
+ token: 'TOKEN',
+ ca_pem: ca_pem)
+ end
+
+ context 'when CA PEM is provided' do
+ let(:ca_pem) { 'PEM' }
+ let(:path) { expand_fixture_path('config/kubeconfig.yml') }
+
+ it { is_expected.to eq(YAML.load_file(path)) }
+ end
+
+ context 'when CA PEM is not provided' do
+ let(:ca_pem) { nil }
+ let(:path) { expand_fixture_path('config/kubeconfig-without-ca.yml') }
+
+ it { is_expected.to eq(YAML.load_file(path)) }
+ end
+ end
end
diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb
index 858ad595dbf..5ba523a478a 100644
--- a/spec/models/project_services/kubernetes_service_spec.rb
+++ b/spec/models/project_services/kubernetes_service_spec.rb
@@ -129,7 +129,7 @@ describe KubernetesService, models: true, caching: true do
it "returns the default namespace" do
is_expected.to eq(service.send(:default_namespace))
end
-
+
context 'when namespace is specified' do
before do
service.namespace = 'my-namespace'
@@ -201,6 +201,22 @@ describe KubernetesService, models: true, caching: true do
end
describe '#predefined_variables' do
+ let(:kubeconfig) do
+ config =
+ YAML.load(File.read(expand_fixture_path('config/kubeconfig.yml')))
+
+ config.dig('users', 0, 'user')['token'] =
+ 'token'
+
+ config.dig('clusters', 0, 'cluster')['certificate-authority-data'] =
+ Base64.encode64('CA PEM DATA')
+
+ config.dig('contexts', 0, 'context')['namespace'] =
+ namespace
+
+ YAML.dump(config)
+ end
+
before do
subject.api_url = 'https://kube.domain.com'
subject.token = 'token'
@@ -208,32 +224,34 @@ describe KubernetesService, models: true, caching: true do
subject.project = project
end
- context 'namespace is provided' do
- before do
- subject.namespace = 'my-project'
- end
-
+ shared_examples 'setting variables' do
it 'sets the variables' do
expect(subject.predefined_variables).to include(
{ key: 'KUBE_URL', value: 'https://kube.domain.com', public: true },
{ key: 'KUBE_TOKEN', value: 'token', public: false },
- { key: 'KUBE_NAMESPACE', value: 'my-project', public: true },
+ { key: 'KUBE_NAMESPACE', value: namespace, public: true },
+ { key: 'KUBECONFIG', value: kubeconfig, public: false, file: true },
{ key: 'KUBE_CA_PEM', value: 'CA PEM DATA', public: true },
{ key: 'KUBE_CA_PEM_FILE', value: 'CA PEM DATA', public: true, file: true }
)
end
end
- context 'no namespace provided' do
- it 'sets the variables' do
- expect(subject.predefined_variables).to include(
- { key: 'KUBE_URL', value: 'https://kube.domain.com', public: true },
- { key: 'KUBE_TOKEN', value: 'token', public: false },
- { key: 'KUBE_CA_PEM', value: 'CA PEM DATA', public: true },
- { key: 'KUBE_CA_PEM_FILE', value: 'CA PEM DATA', public: true, file: true }
- )
+ context 'namespace is provided' do
+ let(:namespace) { 'my-project' }
+
+ before do
+ subject.namespace = namespace
end
+ it_behaves_like 'setting variables'
+ end
+
+ context 'no namespace provided' do
+ let(:namespace) { subject.actual_namespace }
+
+ it_behaves_like 'setting variables'
+
it 'sets the KUBE_NAMESPACE' do
kube_namespace = subject.predefined_variables.find { |h| h[:key] == 'KUBE_NAMESPACE' }