Add helm CLI wrapper
This commit is contained in:
parent
4a9cf1dc00
commit
6d462cea77
|
@ -0,0 +1,57 @@
|
|||
module Gitlab
|
||||
class Helm
|
||||
Error = Class.new(StandardError)
|
||||
|
||||
attr_accessor :namespace
|
||||
attr_accessor :logger
|
||||
|
||||
delegate :debug, :debug?, to: :logger, allow_nil: true
|
||||
|
||||
def initialize(namespace, kubeconfig, logger: nil)
|
||||
self.namespace = namespace
|
||||
self.logger = logger
|
||||
@kubeconfig = kubeconfig
|
||||
end
|
||||
|
||||
def init!
|
||||
prepare_env do |env|
|
||||
helm('init', '--upgrade', env: env)
|
||||
end
|
||||
end
|
||||
|
||||
def install_or_upgrade!(app_name, chart)
|
||||
prepare_env do |env|
|
||||
helm('init', '--client-only', env: env)
|
||||
helm('upgrade', '--install', '--namespace', namespace, app_name, chart, env: env)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare_env(*args, &blk)
|
||||
Dir.mktmpdir(['helm', namespace]) do |tmpdir|
|
||||
kubeconfig_path = File.join(tmpdir, 'kubeconfig')
|
||||
env = {
|
||||
'HELM_HOME' => File.join(tmpdir, 'helm'),
|
||||
'TILLER_NAMESPACE' => namespace,
|
||||
'KUBECONFIG' => kubeconfig_path
|
||||
}
|
||||
|
||||
File.open(kubeconfig_path, 'w') { |c| c << YAML.dump(@kubeconfig) }
|
||||
|
||||
debug("HELM: Running in tmpdir #{tmpdir}")
|
||||
yield(env) if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
def helm(*args, env: {})
|
||||
Open3.popen3(env, 'helm', *args) do |_, stdout, stderr, wait_thr|
|
||||
exit_status = wait_thr.value
|
||||
|
||||
stdout.readlines.each { |l| debug("HELM: #{l.chomp}") } if debug?
|
||||
|
||||
raise Error, stderr.read.chomp unless exit_status.success?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,70 @@
|
|||
# coding: utf-8
|
||||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::Helm do
|
||||
let(:namespace) { 'rails-spec' }
|
||||
let(:kubeconfig) {}
|
||||
let(:logger) {}
|
||||
subject { described_class.new(namespace, kubeconfig, logger: logger)}
|
||||
|
||||
def mock_helm_invocation(success:, error: '')
|
||||
stderr = StringIO.new(error)
|
||||
process_status = double('process_status')
|
||||
wait_thr = double('wait_thread')
|
||||
|
||||
expect(Open3).to receive(:popen3).at_least(:once).and_yield(StringIO.new, StringIO.new, stderr, wait_thr)
|
||||
expect(wait_thr).to receive(:value).at_least(:once).and_return(process_status)
|
||||
expect(process_status).to receive(:success?).at_least(:once).and_return(success)
|
||||
end
|
||||
|
||||
shared_examples 'invokes helm binary' do |method, args|
|
||||
context 'when helm binary fails' do
|
||||
let(:error_text) { 'Something went wrong' }
|
||||
|
||||
before do
|
||||
mock_helm_invocation(success: false, error: error_text)
|
||||
end
|
||||
|
||||
it 'throws exception' do
|
||||
expect { subject.send(method, *args) }.to raise_exception(Gitlab::Helm::Error, error_text)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when helm binary exit-code is 0' do
|
||||
before do
|
||||
mock_helm_invocation(success: true)
|
||||
end
|
||||
|
||||
it "doesn't raise exceptions" do
|
||||
expect { subject.send(method, *args) }.not_to raise_exception
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it { is_expected.to delegate_method(:debug).to(:logger) }
|
||||
it { is_expected.to delegate_method(:debug?).to(:logger) }
|
||||
|
||||
describe '#init!' do
|
||||
it 'invokes helm init --upgrade' do
|
||||
expect(subject).to receive(:helm).with('init', '--upgrade', env: instance_of(Hash))
|
||||
|
||||
subject.init!
|
||||
end
|
||||
|
||||
it_should_behave_like 'invokes helm binary', :init!, []
|
||||
end
|
||||
|
||||
describe '#install_or_upgrade!' do
|
||||
let(:app_name) { 'app_name' }
|
||||
let(:chart) { 'stable/a_chart' }
|
||||
|
||||
it 'invokes helm upgrade --install --namespace namespace app_name chart' do
|
||||
expect(subject).to receive(:helm).with('init', '--client-only', env: instance_of(Hash)).ordered.once
|
||||
expect(subject).to receive(:helm).with('upgrade', '--install', '--namespace', namespace, app_name, chart, env: instance_of(Hash)).ordered.once
|
||||
|
||||
subject.install_or_upgrade!(app_name, chart)
|
||||
end
|
||||
|
||||
it_should_behave_like 'invokes helm binary', :install_or_upgrade!, %w[app_name chart]
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue