Merge branch '33360-generate-kubeconfig' into 'master'
Generate KUBECONFIG in KubernetesService#predefined_variables Closes #33360 See merge request !12223
This commit is contained in:
commit
e0b3257b36
|
@ -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
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Provide KUBECONFIG from KubernetesService for runners
|
||||
merge_request: 12223
|
||||
author:
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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' }
|
||||
|
||||
|
|
Loading…
Reference in New Issue