Commit d4762348 authored by charlie ablett's avatar charlie ablett

Merge branch 'merge-injected-kubeconfigs' into 'master'

Merge injected KUBECONFIGs for clusters and agents

See merge request gitlab-org/gitlab!82246
parents 22ae4726 bc2b67cf
...@@ -19,8 +19,7 @@ module Gitlab ...@@ -19,8 +19,7 @@ module Gitlab
variables.concat(project.predefined_variables) variables.concat(project.predefined_variables)
variables.concat(pipeline.predefined_variables) variables.concat(pipeline.predefined_variables)
variables.concat(job.runner.predefined_variables) if job.runnable? && job.runner variables.concat(job.runner.predefined_variables) if job.runnable? && job.runner
variables.concat(kubernetes_variables(job)) variables.concat(kubernetes_variables(environment: environment, job: job))
variables.concat(deployment_variables(environment: environment, job: job))
variables.concat(job.yaml_variables) variables.concat(job.yaml_variables)
variables.concat(user_variables(job.user)) variables.concat(user_variables(job.user))
variables.concat(job.dependency_variables) if dependencies variables.concat(job.dependency_variables) if dependencies
...@@ -33,11 +32,15 @@ module Gitlab ...@@ -33,11 +32,15 @@ module Gitlab
end end
end end
def kubernetes_variables(job) def kubernetes_variables(environment:, job:)
::Gitlab::Ci::Variables::Collection.new.tap do |collection| ::Gitlab::Ci::Variables::Collection.new.tap do |collection|
# Should get merged with the cluster kubeconfig in deployment_variables, see # NOTE: deployment_variables will be removed as part of cleanup for
# https://gitlab.com/gitlab-org/gitlab/-/issues/335089 # https://gitlab.com/groups/gitlab-org/configure/-/epics/8
# Until then, we need to make both the old and the new KUBECONFIG contexts available
collection.concat(deployment_variables(environment: environment, job: job))
template = ::Ci::GenerateKubeconfigService.new(job).execute template = ::Ci::GenerateKubeconfigService.new(job).execute
kubeconfig_yaml = collection['KUBECONFIG']&.value
template.merge_yaml(kubeconfig_yaml) if kubeconfig_yaml.present?
if template.valid? if template.valid?
collection.append(key: 'KUBECONFIG', value: template.to_yaml, public: false, file: true) collection.append(key: 'KUBECONFIG', value: template.to_yaml, public: false, file: true)
......
...@@ -14,6 +14,7 @@ module Gitlab ...@@ -14,6 +14,7 @@ module Gitlab
@clusters = [] @clusters = []
@users = [] @users = []
@contexts = [] @contexts = []
@current_context = nil
end end
def valid? def valid?
...@@ -32,14 +33,45 @@ module Gitlab ...@@ -32,14 +33,45 @@ module Gitlab
contexts << new_entry(:context, **args) contexts << new_entry(:context, **args)
end end
def merge_yaml(kubeconfig_yaml)
return unless kubeconfig_yaml
kubeconfig_yaml = YAML.safe_load(kubeconfig_yaml, symbolize_names: true)
kubeconfig_yaml[:users].each do |user|
add_user(
name: user[:name],
token: user.dig(:user, :token)
)
end
kubeconfig_yaml[:clusters].each do |cluster|
ca_pem = cluster.dig(:cluster, :'certificate-authority-data')&.yield_self do |data|
Base64.strict_decode64(data)
end
add_cluster(
name: cluster[:name],
url: cluster.dig(:cluster, :server),
ca_pem: ca_pem
)
end
kubeconfig_yaml[:contexts].each do |context|
add_context(
name: context[:name],
**context[:context]&.slice(:cluster, :user, :namespace)
)
end
@current_context = kubeconfig_yaml[:'current-context']
end
def to_h def to_h
{ {
apiVersion: 'v1', apiVersion: 'v1',
kind: 'Config', kind: 'Config',
clusters: clusters.map(&:to_h), clusters: clusters.map(&:to_h),
users: users.map(&:to_h), users: users.map(&:to_h),
contexts: contexts.map(&:to_h) contexts: contexts.map(&:to_h),
} 'current-context': current_context
}.compact
end end
def to_yaml def to_yaml
...@@ -48,7 +80,7 @@ module Gitlab ...@@ -48,7 +80,7 @@ module Gitlab
private private
attr_reader :clusters, :users, :contexts attr_reader :clusters, :users, :contexts, :current_context
def new_entry(entry, **args) def new_entry(entry, **args)
ENTRIES.fetch(entry).new(**args) ENTRIES.fetch(entry).new(**args)
......
...@@ -158,7 +158,6 @@ RSpec.describe Gitlab::Ci::Variables::Builder do ...@@ -158,7 +158,6 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
allow(pipeline).to receive(:predefined_variables) { [var('C', 3), var('D', 3)] } allow(pipeline).to receive(:predefined_variables) { [var('C', 3), var('D', 3)] }
allow(job).to receive(:runner) { double(predefined_variables: [var('D', 4), var('E', 4)]) } allow(job).to receive(:runner) { double(predefined_variables: [var('D', 4), var('E', 4)]) }
allow(builder).to receive(:kubernetes_variables) { [var('E', 5), var('F', 5)] } allow(builder).to receive(:kubernetes_variables) { [var('E', 5), var('F', 5)] }
allow(builder).to receive(:deployment_variables) { [var('F', 6), var('G', 6)] }
allow(job).to receive(:yaml_variables) { [var('G', 7), var('H', 7)] } allow(job).to receive(:yaml_variables) { [var('G', 7), var('H', 7)] }
allow(builder).to receive(:user_variables) { [var('H', 8), var('I', 8)] } allow(builder).to receive(:user_variables) { [var('H', 8), var('I', 8)] }
allow(job).to receive(:dependency_variables) { [var('I', 9), var('J', 9)] } allow(job).to receive(:dependency_variables) { [var('I', 9), var('J', 9)] }
...@@ -177,7 +176,6 @@ RSpec.describe Gitlab::Ci::Variables::Builder do ...@@ -177,7 +176,6 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
var('C', 3), var('D', 3), var('C', 3), var('D', 3),
var('D', 4), var('E', 4), var('D', 4), var('E', 4),
var('E', 5), var('F', 5), var('E', 5), var('F', 5),
var('F', 6), var('G', 6),
var('G', 7), var('H', 7), var('G', 7), var('H', 7),
var('H', 8), var('I', 8), var('H', 8), var('I', 8),
var('I', 9), var('J', 9), var('I', 9), var('J', 9),
...@@ -193,7 +191,7 @@ RSpec.describe Gitlab::Ci::Variables::Builder do ...@@ -193,7 +191,7 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
expect(subject.to_hash).to match( expect(subject.to_hash).to match(
'A' => '1', 'B' => '2', 'A' => '1', 'B' => '2',
'C' => '3', 'D' => '4', 'C' => '3', 'D' => '4',
'E' => '5', 'F' => '6', 'E' => '5', 'F' => '5',
'G' => '7', 'H' => '8', 'G' => '7', 'H' => '8',
'I' => '9', 'J' => '10', 'I' => '9', 'J' => '10',
'K' => '11', 'L' => '12', 'K' => '11', 'L' => '12',
...@@ -231,7 +229,7 @@ RSpec.describe Gitlab::Ci::Variables::Builder do ...@@ -231,7 +229,7 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
let(:template) { double(to_yaml: 'example-kubeconfig', valid?: template_valid) } let(:template) { double(to_yaml: 'example-kubeconfig', valid?: template_valid) }
let(:template_valid) { true } let(:template_valid) { true }
subject { builder.kubernetes_variables(job) } subject { builder.kubernetes_variables(environment: nil, job: job) }
before do before do
allow(Ci::GenerateKubeconfigService).to receive(:new).with(job).and_return(service) allow(Ci::GenerateKubeconfigService).to receive(:new).with(job).and_return(service)
...@@ -244,6 +242,16 @@ RSpec.describe Gitlab::Ci::Variables::Builder do ...@@ -244,6 +242,16 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
it { is_expected.not_to include(key: 'KUBECONFIG', value: 'example-kubeconfig', public: false, file: true) } it { is_expected.not_to include(key: 'KUBECONFIG', value: 'example-kubeconfig', public: false, file: true) }
end end
it 'includes #deployment_variables and merges the KUBECONFIG values', :aggregate_failures do
expect(builder).to receive(:deployment_variables).and_return([
{ key: 'KUBECONFIG', value: 'deployment-kubeconfig' },
{ key: 'OTHER', value: 'some value' }
])
expect(template).to receive(:merge_yaml).with('deployment-kubeconfig')
expect(subject['KUBECONFIG'].value).to eq('example-kubeconfig')
expect(subject['OTHER'].value).to eq('some value')
end
end end
describe '#deployment_variables' do describe '#deployment_variables' do
......
...@@ -39,6 +39,51 @@ RSpec.describe Gitlab::Kubernetes::Kubeconfig::Template do ...@@ -39,6 +39,51 @@ RSpec.describe Gitlab::Kubernetes::Kubeconfig::Template do
it { is_expected.to eq(YAML.dump(template.to_h.deep_stringify_keys)) } it { is_expected.to eq(YAML.dump(template.to_h.deep_stringify_keys)) }
end end
describe '#merge_yaml' do
it 'appends to the configuration and overwrites the current context' do
template.add_cluster(name: 'hello-cluster', url: 'hello-url')
template.add_context(name: 'hello-context', cluster: 'hello-cluster', user: 'hello-user')
template.add_user(name: 'hello-user', token: 'hello-token')
ca_pem = Base64.strict_encode64('a certificate')
template.merge_yaml(<<~YAML)
apiVersion: v1
kind: Config
clusters:
- name: 'gitlab-deploy'
cluster:
server: url
certificate-authority-data: #{ca_pem.inspect}
contexts:
- name: gitlab-deploy
context:
cluster: gitlab-deploy
namespace: namespace
user: gitlab-deploy
current-context: gitlab-deploy
users:
- name: 'gitlab-deploy'
user: { token: token }
YAML
expect(template.to_h).to eq({
apiVersion: 'v1',
kind: 'Config',
clusters: [
{ name: 'hello-cluster', cluster: { server: 'hello-url' } },
{ name: 'gitlab-deploy', cluster: { server: 'url', 'certificate-authority-data': ca_pem } }
],
contexts: [
{ name: 'hello-context', context: { cluster: 'hello-cluster', user: 'hello-user' } },
{ name: 'gitlab-deploy', context: { cluster: 'gitlab-deploy', namespace: 'namespace', user: 'gitlab-deploy' } }
],
users: [
{ name: 'hello-user', user: { token: 'hello-token' } },
{ name: 'gitlab-deploy', user: { token: 'token' } }
],
'current-context': 'gitlab-deploy'
})
end
end
describe 'adding entries' do describe 'adding entries' do
let(:entry) { instance_double(entry_class, to_h: attributes) } let(:entry) { instance_double(entry_class, to_h: attributes) }
let(:attributes) do let(:attributes) do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment