270 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			270 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| require 'spec_helper'
 | |
| 
 | |
| RSpec.describe Gitlab::Kubernetes::Helm::API do
 | |
|   let(:client) { double('kubernetes client') }
 | |
|   let(:helm) { described_class.new(client) }
 | |
|   let(:gitlab_namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
 | |
|   let(:gitlab_namespace_labels) { Gitlab::Kubernetes::Helm::NAMESPACE_LABELS }
 | |
|   let(:namespace) { Gitlab::Kubernetes::Namespace.new(gitlab_namespace, client, labels: gitlab_namespace_labels) }
 | |
|   let(:application_name) { 'app-name' }
 | |
|   let(:rbac) { false }
 | |
|   let(:files) { {} }
 | |
| 
 | |
|   let(:command) do
 | |
|     Gitlab::Kubernetes::Helm::V2::InstallCommand.new(
 | |
|       name: application_name,
 | |
|       chart: 'chart-name',
 | |
|       rbac: rbac,
 | |
|       files: files
 | |
|     )
 | |
|   end
 | |
| 
 | |
|   subject { helm }
 | |
| 
 | |
|   before do
 | |
|     allow(Gitlab::Kubernetes::Namespace).to(
 | |
|       receive(:new).with(gitlab_namespace, client, labels: gitlab_namespace_labels).and_return(namespace)
 | |
|     )
 | |
|     allow(client).to receive(:create_config_map)
 | |
|   end
 | |
| 
 | |
|   describe '#initialize' do
 | |
|     it 'creates a namespace object' do
 | |
|       expect(Gitlab::Kubernetes::Namespace).to(
 | |
|         receive(:new).with(gitlab_namespace, client, labels: gitlab_namespace_labels)
 | |
|       )
 | |
| 
 | |
|       subject
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   describe '#uninstall' do
 | |
|     before do
 | |
|       allow(client).to receive(:create_pod).and_return(nil)
 | |
|       allow(client).to receive(:get_config_map).and_return(nil)
 | |
|       allow(client).to receive(:create_config_map).and_return(nil)
 | |
|       allow(client).to receive(:delete_pod).and_return(nil)
 | |
|       allow(namespace).to receive(:ensure_exists!).once
 | |
|     end
 | |
| 
 | |
|     it 'ensures the namespace exists before creating the POD' do
 | |
|       expect(namespace).to receive(:ensure_exists!).once.ordered
 | |
|       expect(client).to receive(:create_pod).once.ordered
 | |
| 
 | |
|       subject.uninstall(command)
 | |
|     end
 | |
| 
 | |
|     it 'removes an existing pod before installing' do
 | |
|       expect(client).to receive(:delete_pod).with('install-app-name', 'gitlab-managed-apps').once.ordered
 | |
|       expect(client).to receive(:create_pod).once.ordered
 | |
| 
 | |
|       subject.uninstall(command)
 | |
|     end
 | |
| 
 | |
|     context 'with a ConfigMap' do
 | |
|       let(:resource) { Gitlab::Kubernetes::ConfigMap.new(application_name, files).generate }
 | |
| 
 | |
|       it 'creates a ConfigMap on kubeclient' do
 | |
|         expect(client).to receive(:create_config_map).with(resource).once
 | |
| 
 | |
|         subject.install(command)
 | |
|       end
 | |
| 
 | |
|       context 'config map already exists' do
 | |
|         before do
 | |
|           expect(client).to receive(:get_config_map).with("values-content-configuration-#{application_name}", gitlab_namespace).and_return(resource)
 | |
|         end
 | |
| 
 | |
|         it 'updates the config map' do
 | |
|           expect(client).to receive(:update_config_map).with(resource).once
 | |
| 
 | |
|           subject.install(command)
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   describe '#install' do
 | |
|     before do
 | |
|       allow(client).to receive(:create_pod).and_return(nil)
 | |
|       allow(client).to receive(:get_config_map).and_return(nil)
 | |
|       allow(client).to receive(:create_config_map).and_return(nil)
 | |
|       allow(client).to receive(:create_service_account).and_return(nil)
 | |
|       allow(client).to receive(:delete_pod).and_return(nil)
 | |
|       allow(namespace).to receive(:ensure_exists!).once
 | |
|     end
 | |
| 
 | |
|     it 'ensures the namespace exists before creating the POD' do
 | |
|       expect(namespace).to receive(:ensure_exists!).once.ordered
 | |
|       expect(client).to receive(:create_pod).once.ordered
 | |
| 
 | |
|       subject.install(command)
 | |
|     end
 | |
| 
 | |
|     it 'removes an existing pod before installing' do
 | |
|       expect(client).to receive(:delete_pod).with('install-app-name', 'gitlab-managed-apps').once.ordered
 | |
|       expect(client).to receive(:create_pod).once.ordered
 | |
| 
 | |
|       subject.install(command)
 | |
|     end
 | |
| 
 | |
|     context 'with a ConfigMap' do
 | |
|       let(:resource) { Gitlab::Kubernetes::ConfigMap.new(application_name, files).generate }
 | |
| 
 | |
|       it 'creates a ConfigMap on kubeclient' do
 | |
|         expect(client).to receive(:create_config_map).with(resource).once
 | |
| 
 | |
|         subject.install(command)
 | |
|       end
 | |
| 
 | |
|       context 'config map already exists' do
 | |
|         before do
 | |
|           expect(client).to receive(:get_config_map).with("values-content-configuration-#{application_name}", gitlab_namespace).and_return(resource)
 | |
|         end
 | |
| 
 | |
|         it 'updates the config map' do
 | |
|           expect(client).to receive(:update_config_map).with(resource).once
 | |
| 
 | |
|           subject.install(command)
 | |
|         end
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'without a service account' do
 | |
|       it 'does not create a service account on kubeclient' do
 | |
|         expect(client).not_to receive(:create_service_account)
 | |
|         expect(client).not_to receive(:update_cluster_role_binding)
 | |
| 
 | |
|         subject.install(command)
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'with a service account' do
 | |
|       let(:command) { Gitlab::Kubernetes::Helm::V2::InitCommand.new(name: application_name, files: files, rbac: rbac) }
 | |
| 
 | |
|       context 'rbac-enabled cluster' do
 | |
|         let(:rbac) { true }
 | |
| 
 | |
|         let(:service_account_resource) do
 | |
|           Kubeclient::Resource.new(metadata: { name: 'tiller', namespace: 'gitlab-managed-apps' })
 | |
|         end
 | |
| 
 | |
|         let(:cluster_role_binding_resource) do
 | |
|           Kubeclient::Resource.new(
 | |
|             metadata: { name: 'tiller-admin' },
 | |
|             roleRef: { apiGroup: 'rbac.authorization.k8s.io', kind: 'ClusterRole', name: 'cluster-admin' },
 | |
|             subjects: [{ kind: 'ServiceAccount', name: 'tiller', namespace: 'gitlab-managed-apps' }]
 | |
|           )
 | |
|         end
 | |
| 
 | |
|         context 'service account does not exist' do
 | |
|           before do
 | |
|             expect(client).to receive(:get_service_account).with('tiller', 'gitlab-managed-apps').and_raise(Kubeclient::ResourceNotFoundError.new(404, 'Not found', nil))
 | |
|           end
 | |
| 
 | |
|           it 'creates a service account, followed the cluster role binding on kubeclient' do
 | |
|             expect(client).to receive(:create_service_account).with(service_account_resource).once.ordered
 | |
|             expect(client).to receive(:update_cluster_role_binding).with(cluster_role_binding_resource).once.ordered
 | |
| 
 | |
|             subject.install(command)
 | |
|           end
 | |
|         end
 | |
| 
 | |
|         context 'service account already exists' do
 | |
|           before do
 | |
|             expect(client).to receive(:get_service_account).with('tiller', 'gitlab-managed-apps').and_return(service_account_resource)
 | |
|           end
 | |
| 
 | |
|           it 'updates the service account, followed by creating the cluster role binding' do
 | |
|             expect(client).to receive(:update_service_account).with(service_account_resource).once.ordered
 | |
|             expect(client).to receive(:update_cluster_role_binding).with(cluster_role_binding_resource).once.ordered
 | |
| 
 | |
|             subject.install(command)
 | |
|           end
 | |
|         end
 | |
| 
 | |
|         context 'a non-404 error is thrown' do
 | |
|           before do
 | |
|             expect(client).to receive(:get_service_account).with('tiller', 'gitlab-managed-apps').and_raise(Kubeclient::HttpError.new(401, 'Unauthorized', nil))
 | |
|           end
 | |
| 
 | |
|           it 'raises an error' do
 | |
|             expect { subject.install(command) }.to raise_error(Kubeclient::HttpError)
 | |
|           end
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       context 'legacy abac cluster' do
 | |
|         it 'does not create a service account on kubeclient' do
 | |
|           expect(client).not_to receive(:create_service_account)
 | |
|           expect(client).not_to receive(:update_cluster_role_binding)
 | |
| 
 | |
|           subject.install(command)
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   describe '#status' do
 | |
|     let(:phase) { Gitlab::Kubernetes::Pod::RUNNING }
 | |
|     let(:pod) { Kubeclient::Resource.new(status: { phase: phase }) } # partial representation
 | |
| 
 | |
|     it 'fetches POD phase from kubernetes cluster' do
 | |
|       expect(client).to receive(:get_pod).with(command.pod_name, gitlab_namespace).once.and_return(pod)
 | |
| 
 | |
|       expect(subject.status(command.pod_name)).to eq(phase)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   describe '#log' do
 | |
|     let(:log) { 'some output' }
 | |
|     let(:response) { RestClient::Response.new(log) }
 | |
| 
 | |
|     it 'fetches POD phase from kubernetes cluster' do
 | |
|       expect(client).to receive(:get_pod_log).with(command.pod_name, gitlab_namespace).once.and_return(response)
 | |
| 
 | |
|       expect(subject.log(command.pod_name)).to eq(log)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   describe '#delete_pod!' do
 | |
|     it 'deletes the POD from kubernetes cluster' do
 | |
|       expect(client).to receive(:delete_pod).with('install-app-name', 'gitlab-managed-apps').once
 | |
| 
 | |
|       subject.delete_pod!('install-app-name')
 | |
|     end
 | |
| 
 | |
|     context 'when the resource being deleted does not exist' do
 | |
|       it 'catches the error' do
 | |
|         expect(client).to receive(:delete_pod).with('install-app-name', 'gitlab-managed-apps')
 | |
|           .and_raise(Kubeclient::ResourceNotFoundError.new(404, 'Not found', nil))
 | |
| 
 | |
|         subject.delete_pod!('install-app-name')
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   describe '#get_config_map' do
 | |
|     before do
 | |
|       allow(namespace).to receive(:ensure_exists!).once
 | |
|       allow(client).to receive(:get_config_map).and_return(nil)
 | |
|     end
 | |
| 
 | |
|     it 'ensures the namespace exists before retrieving the config map' do
 | |
|       expect(namespace).to receive(:ensure_exists!).once
 | |
| 
 | |
|       subject.get_config_map('example-config-map-name')
 | |
|     end
 | |
| 
 | |
|     it 'gets the config map on kubeclient' do
 | |
|       expect(client).to receive(:get_config_map)
 | |
|         .with('example-config-map-name', namespace.name)
 | |
|         .once
 | |
| 
 | |
|       subject.get_config_map('example-config-map-name')
 | |
|     end
 | |
|   end
 | |
| end
 |