dc18272091
If the service fails mid-point, then we should be able to re-run this service. So, detect presence of any previously created Kubernetes resource and update or create accordingly. Fix specs accordingly. In the case of finalize_creation_service_spec.rb, I decided to stub out the async worker rather than maintaining individual stubs for various kubeclient calls for that worker. Also add test cases for group clusters
265 lines
6.7 KiB
Ruby
265 lines
6.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
describe Gitlab::Kubernetes::KubeClient do
|
|
include KubernetesHelpers
|
|
|
|
let(:api_url) { 'https://kubernetes.example.com/prefix' }
|
|
let(:kubeclient_options) { { auth_options: { bearer_token: 'xyz' } } }
|
|
|
|
let(:client) { described_class.new(api_url, kubeclient_options) }
|
|
|
|
before do
|
|
stub_kubeclient_discover(api_url)
|
|
end
|
|
|
|
shared_examples 'a Kubeclient' do
|
|
it 'is a Kubeclient::Client' do
|
|
is_expected.to be_an_instance_of Kubeclient::Client
|
|
end
|
|
|
|
it 'has the kubeclient options' do
|
|
expect(subject.auth_options).to eq({ bearer_token: 'xyz' })
|
|
end
|
|
end
|
|
|
|
describe '#core_client' do
|
|
subject { client.core_client }
|
|
|
|
it_behaves_like 'a Kubeclient'
|
|
|
|
it 'has the core API endpoint' do
|
|
expect(subject.api_endpoint.to_s).to match(%r{\/api\Z})
|
|
end
|
|
|
|
it 'has the api_version' do
|
|
expect(subject.instance_variable_get(:@api_version)).to eq('v1')
|
|
end
|
|
end
|
|
|
|
describe '#rbac_client' do
|
|
subject { client.rbac_client }
|
|
|
|
it_behaves_like 'a Kubeclient'
|
|
|
|
it 'has the RBAC API group endpoint' do
|
|
expect(subject.api_endpoint.to_s).to match(%r{\/apis\/rbac.authorization.k8s.io\Z})
|
|
end
|
|
|
|
it 'has the api_version' do
|
|
expect(subject.instance_variable_get(:@api_version)).to eq('v1')
|
|
end
|
|
end
|
|
|
|
describe '#extensions_client' do
|
|
subject { client.extensions_client }
|
|
|
|
it_behaves_like 'a Kubeclient'
|
|
|
|
it 'has the extensions API group endpoint' do
|
|
expect(subject.api_endpoint.to_s).to match(%r{\/apis\/extensions\Z})
|
|
end
|
|
|
|
it 'has the api_version' do
|
|
expect(subject.instance_variable_get(:@api_version)).to eq('v1beta1')
|
|
end
|
|
end
|
|
|
|
describe '#knative_client' do
|
|
subject { client.knative_client }
|
|
|
|
it_behaves_like 'a Kubeclient'
|
|
|
|
it 'has the extensions API group endpoint' do
|
|
expect(subject.api_endpoint.to_s).to match(%r{\/apis\/serving.knative.dev\Z})
|
|
end
|
|
|
|
it 'has the api_version' do
|
|
expect(subject.instance_variable_get(:@api_version)).to eq('v1alpha1')
|
|
end
|
|
end
|
|
|
|
describe 'core API' do
|
|
let(:core_client) { client.core_client }
|
|
|
|
[
|
|
:get_pods,
|
|
:get_secrets,
|
|
:get_config_map,
|
|
:get_pod,
|
|
:get_namespace,
|
|
:get_secret,
|
|
:get_service,
|
|
:get_service_account,
|
|
:delete_pod,
|
|
:create_config_map,
|
|
:create_namespace,
|
|
:create_pod,
|
|
:create_secret,
|
|
:create_service_account,
|
|
:update_config_map,
|
|
:update_secret,
|
|
:update_service_account
|
|
].each do |method|
|
|
describe "##{method}" do
|
|
it 'delegates to the core client' do
|
|
expect(client).to delegate_method(method).to(:core_client)
|
|
end
|
|
|
|
it 'responds to the method' do
|
|
expect(client).to respond_to method
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'rbac API group' do
|
|
let(:rbac_client) { client.rbac_client }
|
|
|
|
[
|
|
:create_cluster_role_binding,
|
|
:get_cluster_role_binding,
|
|
:update_cluster_role_binding
|
|
].each do |method|
|
|
describe "##{method}" do
|
|
it 'delegates to the rbac client' do
|
|
expect(client).to delegate_method(method).to(:rbac_client)
|
|
end
|
|
|
|
it 'responds to the method' do
|
|
expect(client).to respond_to method
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'extensions API group' do
|
|
let(:api_groups) { ['apis/extensions'] }
|
|
let(:extensions_client) { client.extensions_client }
|
|
|
|
describe '#get_deployments' do
|
|
it 'delegates to the extensions client' do
|
|
expect(client).to delegate_method(:get_deployments).to(:extensions_client)
|
|
end
|
|
|
|
it 'responds to the method' do
|
|
expect(client).to respond_to :get_deployments
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'non-entity methods' do
|
|
it 'does not proxy for non-entity methods' do
|
|
expect(client).not_to respond_to :proxy_url
|
|
end
|
|
|
|
it 'throws an error' do
|
|
expect { client.proxy_url }.to raise_error(NoMethodError)
|
|
end
|
|
end
|
|
|
|
describe '#get_pod_log' do
|
|
let(:core_client) { client.core_client }
|
|
|
|
it 'is delegated to the core client' do
|
|
expect(client).to delegate_method(:get_pod_log).to(:core_client)
|
|
end
|
|
end
|
|
|
|
describe '#watch_pod_log' do
|
|
let(:core_client) { client.core_client }
|
|
|
|
it 'is delegated to the core client' do
|
|
expect(client).to delegate_method(:watch_pod_log).to(:core_client)
|
|
end
|
|
end
|
|
|
|
shared_examples 'create_or_update method' do
|
|
let(:get_method) { "get_#{resource_type}" }
|
|
let(:update_method) { "update_#{resource_type}" }
|
|
let(:create_method) { "create_#{resource_type}" }
|
|
|
|
context 'resource exists' do
|
|
before do
|
|
expect(client).to receive(get_method).and_return(resource)
|
|
end
|
|
|
|
it 'calls the update method' do
|
|
expect(client).to receive(update_method).with(resource)
|
|
|
|
subject
|
|
end
|
|
end
|
|
|
|
context 'resource does not exist' do
|
|
before do
|
|
expect(client).to receive(get_method).and_raise(Kubeclient::ResourceNotFoundError.new(404, 'Not found', nil))
|
|
end
|
|
|
|
it 'calls the create method' do
|
|
expect(client).to receive(create_method).with(resource)
|
|
|
|
subject
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#create_or_update_cluster_role_binding' do
|
|
let(:resource_type) { 'cluster_role_binding' }
|
|
|
|
let(:resource) do
|
|
::Kubeclient::Resource.new(metadata: { name: 'name', namespace: 'namespace' })
|
|
end
|
|
|
|
subject { client.create_or_update_cluster_role_binding(resource) }
|
|
|
|
it_behaves_like 'create_or_update method'
|
|
end
|
|
|
|
describe '#create_or_update_role_binding' do
|
|
let(:resource_type) { 'role_binding' }
|
|
|
|
let(:resource) do
|
|
::Kubeclient::Resource.new(metadata: { name: 'name', namespace: 'namespace' })
|
|
end
|
|
|
|
subject { client.create_or_update_role_binding(resource) }
|
|
|
|
it_behaves_like 'create_or_update method'
|
|
end
|
|
|
|
describe '#create_or_update_service_account' do
|
|
let(:resource_type) { 'service_account' }
|
|
|
|
let(:resource) do
|
|
::Kubeclient::Resource.new(metadata: { name: 'name', namespace: 'namespace' })
|
|
end
|
|
|
|
subject { client.create_or_update_service_account(resource) }
|
|
|
|
it_behaves_like 'create_or_update method'
|
|
end
|
|
|
|
describe '#create_or_update_secret' do
|
|
let(:resource_type) { 'secret' }
|
|
|
|
let(:resource) do
|
|
::Kubeclient::Resource.new(metadata: { name: 'name', namespace: 'namespace' })
|
|
end
|
|
|
|
subject { client.create_or_update_secret(resource) }
|
|
|
|
it_behaves_like 'create_or_update method'
|
|
end
|
|
|
|
describe 'methods that do not exist on any client' do
|
|
it 'throws an error' do
|
|
expect { client.non_existent_method }.to raise_error(NoMethodError)
|
|
end
|
|
|
|
it 'returns false for respond_to' do
|
|
expect(client.respond_to?(:non_existent_method)).to be_falsey
|
|
end
|
|
end
|
|
end
|