Commit 3f261a49 authored by Alessio Caiazza's avatar Alessio Caiazza

Add k8s namespace implementation and tests

parent a03b5d22
...@@ -14,6 +14,7 @@ module Gitlab ...@@ -14,6 +14,7 @@ module Gitlab
def initialize(kubeclient) def initialize(kubeclient)
@kubeclient = kubeclient @kubeclient = kubeclient
@namespace = Namespace.new(NAMESPACE, kubeclient)
end end
def init! def init!
...@@ -21,7 +22,7 @@ module Gitlab ...@@ -21,7 +22,7 @@ module Gitlab
end end
def install(app) def install(app)
create_namespace! unless has_namespace? @namespace.ensure_exists!
@kubeclient.create_pod(pod_resource(app)) @kubeclient.create_pod(pod_resource(app))
end end
...@@ -33,15 +34,15 @@ module Gitlab ...@@ -33,15 +34,15 @@ module Gitlab
# values: "Pending", "Running", "Succeeded", "Failed", "Unknown" # values: "Pending", "Running", "Succeeded", "Failed", "Unknown"
# #
def installation_status(app) def installation_status(app)
@kubeclient.get_pod(pod_name(app), NAMESPACE).status.phase @kubeclient.get_pod(pod_name(app), @namespace.name).status.phase
end end
def installation_log(app) def installation_log(app)
@kubeclient.get_pod_log(pod_name(app), NAMESPACE).body @kubeclient.get_pod_log(pod_name(app), @namespace.name).body
end end
def delete_installation_pod!(app) def delete_installation_pod!(app)
@kubeclient.delete_pod(pod_name(app), NAMESPACE) @kubeclient.delete_pod(pod_name(app), @namespace.name)
end end
private private
...@@ -52,7 +53,7 @@ module Gitlab ...@@ -52,7 +53,7 @@ module Gitlab
def pod_resource(app) def pod_resource(app)
labels = { 'gitlab.org/action': 'install', 'gitlab.org/application': app.name } labels = { 'gitlab.org/action': 'install', 'gitlab.org/application': app.name }
metadata = { name: pod_name(app), namespace: NAMESPACE, labels: labels } metadata = { name: pod_name(app), namespace: @namespace.name, labels: labels }
container = { container = {
name: 'helm', name: 'helm',
image: 'alpine:3.6', image: 'alpine:3.6',
...@@ -83,26 +84,6 @@ module Gitlab ...@@ -83,26 +84,6 @@ module Gitlab
def helm_install_comand(app) def helm_install_comand(app)
"install #{app.chart} --name #{app.name} --namespace #{NAMESPACE}" "install #{app.chart} --name #{app.name} --namespace #{NAMESPACE}"
end end
def has_namespace?
return @has_namespace if defined?(@has_namespace)
begin
@kubeclient.get_namespace(NAMESPACE)
@has_namespace = true
rescue KubeException => ke
raise ke unless ke.error_code == 404
false
end
end
def create_namespace!
namespace_resource = ::Kubeclient::Resource.new
namespace_resource.metadata = {}
namespace_resource.metadata.name = NAMESPACE
@kubeclient.create_namespace(namespace_resource)
end
end end
end end
end end
module Gitlab
module Kubernetes
class Namespace
attr_accessor :name
def initialize(name, client)
self.name = name
@client = client
end
def exists?
@client.get_namespace(name)
rescue ::KubeException => ke
raise ke unless ke.error_code == 404
false
end
def create!
resource = ::Kubeclient::Resource.new(metadata: { name: name })
@client.create_namespace(resource)
end
def ensure_exists!
exists? || create!
end
end
end
end
require 'spec_helper'
describe Gitlab::Kubernetes::Namespace do
let(:name) { 'a_namespace' }
let(:client) { double('kubernetes client') }
subject { described_class.new(name, client) }
it { expect(subject.name).to eq(name) }
describe '#exists?' do
context 'when namespace do not exits' do
let(:exception) { ::KubeException.new(404, "namespace #{name} not found", nil) }
it 'returns false' do
expect(client).to receive(:get_namespace).with(name).once.and_raise(exception)
expect(subject.exists?).to be_falsey
end
end
context 'when namespace exits' do
let(:namespace) { ::Kubeclient::Resource.new(kind: 'Namespace', metadata: { name: name }) } # partial representation
it 'returns true' do
expect(client).to receive(:get_namespace).with(name).once.and_return(namespace)
expect(subject.exists?).to be_truthy
end
end
context 'when cluster cannot be reached' do
let(:exception) { Errno::ECONNREFUSED.new }
it 'raises exception' do
expect(client).to receive(:get_namespace).with(name).once.and_raise(exception)
expect { subject.exists? }.to raise_error(exception)
end
end
end
describe '#create!' do
it 'creates a namespace' do
matcher = have_attributes(metadata: have_attributes(name: name))
expect(client).to receive(:create_namespace).with(matcher).once
expect { subject.create! }.not_to raise_error
end
end
describe '#ensure_exists!' do
it 'checks for existing namespace before creating' do
expect(subject).to receive(:exists?).once.ordered.and_return(false)
expect(subject).to receive(:create!).once.ordered
subject.ensure_exists!
end
it 'do not re-create an existing namespace' do
expect(subject).to receive(:exists?).once.and_return(true)
expect(subject).not_to receive(:create!)
subject.ensure_exists!
end
end
end
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