130 lines
4.4 KiB
Ruby
130 lines
4.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe Clusters::Aws::ProvisionService do
|
|
describe '#execute' do
|
|
let(:provider) { create(:cluster_provider_aws) }
|
|
|
|
let(:provision_role) { create(:aws_role, user: provider.created_by_user) }
|
|
let(:client) { instance_double(Aws::CloudFormation::Client, create_stack: true) }
|
|
let(:cloudformation_template) { double }
|
|
let(:credentials) do
|
|
instance_double(
|
|
Aws::Credentials,
|
|
access_key_id: 'key',
|
|
secret_access_key: 'secret',
|
|
session_token: 'token'
|
|
)
|
|
end
|
|
|
|
let(:parameters) do
|
|
[
|
|
{ parameter_key: 'ClusterName', parameter_value: provider.cluster.name },
|
|
{ parameter_key: 'ClusterRole', parameter_value: provider.role_arn },
|
|
{ parameter_key: 'KubernetesVersion', parameter_value: provider.kubernetes_version },
|
|
{ parameter_key: 'ClusterControlPlaneSecurityGroup', parameter_value: provider.security_group_id },
|
|
{ parameter_key: 'VpcId', parameter_value: provider.vpc_id },
|
|
{ parameter_key: 'Subnets', parameter_value: provider.subnet_ids.join(',') },
|
|
{ parameter_key: 'NodeAutoScalingGroupDesiredCapacity', parameter_value: provider.num_nodes.to_s },
|
|
{ parameter_key: 'NodeInstanceType', parameter_value: provider.instance_type },
|
|
{ parameter_key: 'KeyName', parameter_value: provider.key_name }
|
|
]
|
|
end
|
|
|
|
subject { described_class.new.execute(provider) }
|
|
|
|
before do
|
|
allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
|
|
.with(provision_role, provider: provider)
|
|
.and_return(double(execute: credentials))
|
|
|
|
allow(provider).to receive(:api_client)
|
|
.and_return(client)
|
|
|
|
stub_file_read(Rails.root.join('vendor', 'aws', 'cloudformation', 'eks_cluster.yaml'), content: cloudformation_template)
|
|
end
|
|
|
|
it 'updates the provider status to :creating and configures the provider with credentials' do
|
|
subject
|
|
|
|
expect(provider).to be_creating
|
|
expect(provider.access_key_id).to eq 'key'
|
|
expect(provider.secret_access_key).to eq 'secret'
|
|
expect(provider.session_token).to eq 'token'
|
|
end
|
|
|
|
it 'creates a CloudFormation stack' do
|
|
expect(client).to receive(:create_stack).with(
|
|
stack_name: provider.cluster.name,
|
|
template_body: cloudformation_template,
|
|
parameters: parameters,
|
|
capabilities: ["CAPABILITY_IAM"]
|
|
)
|
|
|
|
subject
|
|
end
|
|
|
|
it 'schedules a worker to monitor creation status' do
|
|
expect(WaitForClusterCreationWorker).to receive(:perform_in)
|
|
.with(Clusters::Aws::VerifyProvisionStatusService::INITIAL_INTERVAL, provider.cluster_id)
|
|
|
|
subject
|
|
end
|
|
|
|
describe 'error handling' do
|
|
shared_examples 'provision error' do |message|
|
|
it "sets the status to :errored with an appropriate error message" do
|
|
subject
|
|
|
|
expect(provider).to be_errored
|
|
expect(provider.status_reason).to include(message)
|
|
end
|
|
end
|
|
|
|
context 'invalid state transition' do
|
|
before do
|
|
allow(provider).to receive(:make_creating).and_return(false)
|
|
end
|
|
|
|
include_examples 'provision error', 'Failed to update provider record'
|
|
end
|
|
|
|
context 'AWS role is not configured' do
|
|
before do
|
|
allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
|
|
.and_raise(Clusters::Aws::FetchCredentialsService::MissingRoleError)
|
|
end
|
|
|
|
include_examples 'provision error', 'Amazon role is not configured'
|
|
end
|
|
|
|
context 'AWS credentials are not configured' do
|
|
before do
|
|
allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
|
|
.and_raise(Aws::Errors::MissingCredentialsError)
|
|
end
|
|
|
|
include_examples 'provision error', 'Amazon credentials are not configured'
|
|
end
|
|
|
|
context 'Authentication failure' do
|
|
before do
|
|
allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
|
|
.and_raise(Aws::STS::Errors::ServiceError.new(double, 'Error message'))
|
|
end
|
|
|
|
include_examples 'provision error', 'Amazon authentication failed'
|
|
end
|
|
|
|
context 'CloudFormation failure' do
|
|
before do
|
|
allow(client).to receive(:create_stack)
|
|
.and_raise(Aws::CloudFormation::Errors::ServiceError.new(double, 'Error message'))
|
|
end
|
|
|
|
include_examples 'provision error', 'Amazon CloudFormation request failed'
|
|
end
|
|
end
|
|
end
|
|
end
|