diff --git a/devops-service/app/api2/routes/stack.rb b/devops-service/app/api2/routes/stack.rb index 494c859..142bc31 100644 --- a/devops-service/app/api2/routes/stack.rb +++ b/devops-service/app/api2/routes/stack.rb @@ -16,7 +16,7 @@ module Devops json Devops::API2_0::Handler::Stack.new(request).stacks_for_provider(provider).map(&:to_hash) end - app.post_with_headers "/stack", :headers => [:accept] do + app.post_with_headers "/stack", :headers => [:accept, :content_type] do check_privileges("stack", "w") json Devops::API2_0::Handler::Stack.new(request).create_stack #create_response "Created", nil, 201 diff --git a/devops-service/providers/base_provider.rb b/devops-service/providers/base_provider.rb index b2fd75d..fa82f9b 100644 --- a/devops-service/providers/base_provider.rb +++ b/devops-service/providers/base_provider.rb @@ -29,5 +29,13 @@ module Provider def unset_tags instance_id, tags end + def create_default_chef_node_name s + "#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}" + end + + def create_default_stack_name s + "stack_#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}" + end + end end diff --git a/devops-service/providers/ec2.rb b/devops-service/providers/ec2.rb index 95476a3..3646df1 100644 --- a/devops-service/providers/ec2.rb +++ b/devops-service/providers/ec2.rb @@ -157,10 +157,6 @@ module Provider true end - def create_default_chef_node_name s - "#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}" - end - def delete_server s r = self.compute.terminate_instances(s.id) i = r.body["instancesSet"][0] @@ -202,6 +198,63 @@ module Provider def compute connection_compute(connection_options) end + + def cloud_formation + @cloud_formation ||= Fog::AWS::CloudFormation.new(connection_options) + end + + def create_stack(stack, out) + begin + out << "Creating stack for project '#{stack.project}' and environment '#{stack.deploy_env}'...\n" + stack.name = create_default_stack_name(stack) unless stack.name + out << "Stack name: #{stack.name}\n" + out << "Stack template: #{stack.stack_template}\n" + out << "Stack parameters: #{stack.parameters}\n" + out << "Stack template: #{stack.template_body}\n" + response = cloud_formation.create_stack(stack.name, + { + 'TemplateBody' => stack.template_body, + 'Parameters' => stack.parameters || {} + } + ) + stack.id = response.body['StackId'] + rescue Excon::Errors::Conflict => e + raise ProviderErrors::NameConflict + rescue Excon::Errors::BadRequest => br + response = ::Chef::JSONCompat.from_json(br.response.body) + if response['code'] == 400 + out << "\nERROR: Bad request (400): #{response['explanation']}" + out << "\n" + raise InvalidRecord.new(response['explanation']) + else + out << "\nERROR: Unknown server error (#{response['code']}): #{response['explanation']}" + out << "\n" + raise InvalidRecord.new(response['explanation']) + end + end + end + + def delete_stack(stack) + fog_stack(stack).destroy + end + + def stack_details(stack) + fog_stack(stack).details + end + + def stack_resources(stack) + fog_stack(stack).resources + end + + def stack_resource(stack, resource_id) + physical_id = fog_stack(stack).resources.get(resource_id).physical_resource_id + compute.servers.get(physical_id) + end + + def stack_servers(stack) + fog_stack(stack).resources.map{|r| compute.servers.get(r.physical_resource_id)} + end + private def convert_groups list res = {} @@ -252,5 +305,9 @@ module Provider end r end + + def fog_stack(stack) + cloud_formation.stacks.get(stack.name, stack.id) + end end end diff --git a/devops-service/providers/openstack.rb b/devops-service/providers/openstack.rb index bda77ea..8602f9f 100644 --- a/devops-service/providers/openstack.rb +++ b/devops-service/providers/openstack.rb @@ -161,14 +161,6 @@ module Provider true end - def create_default_chef_node_name s - "#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}" - end - - def create_default_stack_name s - "stack_#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}" - end - def delete_server s r = self.compute.delete_server(s.id) return r.status == 204 ? "Server with id '#{s.id}' terminated" : r.body @@ -211,7 +203,6 @@ module Provider response = orchestration.create_stack( stack_name: stack.name, template: stack.template_body, - tenant_id: connection_options[:openstack_tenant], parameters: stack.parameters || {} ) stack.id = response[:body]['stack']['id']