From 21cfbd89731d68a0878421ef6488815bf3b116b0 Mon Sep 17 00:00:00 2001 From: amartynov Date: Fri, 14 Aug 2015 17:48:07 +0300 Subject: [PATCH] fixed openstack provider to create stack --- devops-service/app/api2/handlers/stack.rb | 20 ++++++---- .../app/api2/handlers/stack_template.rb | 4 +- devops-service/app/api2/routes/stack.rb | 4 +- .../app/api2/routes/stack_template.rb | 5 ++- .../db/mongo/connectors/stack_template.rb | 1 + .../db/mongo/models/stack/stack_base.rb | 10 ++--- .../db/mongo/models/stack/stack_factory.rb | 4 +- .../stack_template/stack_template_factory.rb | 4 +- devops-service/db/mongo/mongo_connector.rb | 2 +- devops-service/providers/openstack.rb | 22 +++++++++-- .../workers/stack_bootstrap_worker.rb | 39 +++++++++---------- 11 files changed, 70 insertions(+), 45 deletions(-) diff --git a/devops-service/app/api2/handlers/stack.rb b/devops-service/app/api2/handlers/stack.rb index ce9ec93..9c277e8 100644 --- a/devops-service/app/api2/handlers/stack.rb +++ b/devops-service/app/api2/handlers/stack.rb @@ -18,6 +18,7 @@ module Devops Devops::Db.connector.stacks(provider) end +=begin def create_stack object object[:owner] = owner_from_request file = JobStarter.start_job(:worker, :stack_bootstrap, @@ -29,21 +30,26 @@ module Devops stack end +=end def create_stack object = parser.create - stack_model = Model::StackFactory.create(object['provider'], object) - stack_model.owner = owner_from_request - Devops::Db.connector.stack_insert(stack_model) + project = Devops::Db.connector.project(object["project"]) + env = project.deploy_env(object["deploy_env"]) + raise InvalidRecord.new("Environment '#{env.identifier}' of project '#{project.id}' has no stack template") if env.stack_template.nil? + object["stack_template"] = env.stack_template + object["owner"] = parser.current_user +# stack_model = Model::StackFactory.create(env.provider, object) +# stack_model.owner = owner_from_request + #Devops::Db.connector.stack_insert(stack_model) file = JobStarter.start_job(:worker, :stack_bootstrap, - provider: stack_model.provider, - stack_id: stack_model.id, + provider: env.provider, + stack_attributes: object, request: @request ) puts "Syncing report is located here: #{file}" - - stack_model + [file] end def stack id diff --git a/devops-service/app/api2/handlers/stack_template.rb b/devops-service/app/api2/handlers/stack_template.rb index 916ed0c..ff70ec3 100644 --- a/devops-service/app/api2/handlers/stack_template.rb +++ b/devops-service/app/api2/handlers/stack_template.rb @@ -17,9 +17,9 @@ module Devops Devops::Db.connector.stack_templates(provider) end - def create_stack_template + def create_stack_template provider body = parser.create - template_model = Model::StackTemplateFactory.create(body['provider'], body) + template_model = Model::StackTemplateFactory.create(provider, {'template_body' => body.to_json}) Devops::Db.connector.stack_template_insert(template_model) template_model end diff --git a/devops-service/app/api2/routes/stack.rb b/devops-service/app/api2/routes/stack.rb index c3aa9a3..494c859 100644 --- a/devops-service/app/api2/routes/stack.rb +++ b/devops-service/app/api2/routes/stack.rb @@ -18,8 +18,8 @@ module Devops app.post_with_headers "/stack", :headers => [:accept] do check_privileges("stack", "w") - m = Devops::API2_0::Handler::Stack.new(request).create_stack - create_response "Created", m.to_hash, 201 + json Devops::API2_0::Handler::Stack.new(request).create_stack + #create_response "Created", nil, 201 end hash = {} diff --git a/devops-service/app/api2/routes/stack_template.rb b/devops-service/app/api2/routes/stack_template.rb index 66f538a..aa8a4db 100644 --- a/devops-service/app/api2/routes/stack_template.rb +++ b/devops-service/app/api2/routes/stack_template.rb @@ -15,9 +15,10 @@ module Devops json Devops::API2_0::Handler::StackTemplate.new(request).stack_templates_for_provider(provider).map(&:to_hash) end - app.post_with_headers "/stack_template", :headers => [:accept] do + app.post_with_headers "/stack_template/:provider", :headers => [:accept] do |provider| check_privileges('stack_template', 'w') - model = Devops::API2_0::Handler::StackTemplate.new(request).create_stack_template() + check_provider(provider) + model = Devops::API2_0::Handler::StackTemplate.new(request).create_stack_template(provider) create_response 'Created', model.to_hash, 201 end diff --git a/devops-service/db/mongo/connectors/stack_template.rb b/devops-service/db/mongo/connectors/stack_template.rb index d1202b0..172f1a1 100644 --- a/devops-service/db/mongo/connectors/stack_template.rb +++ b/devops-service/db/mongo/connectors/stack_template.rb @@ -1,3 +1,4 @@ +require "db/mongo/models/stack_template/stack_template_factory" module Connectors class StackTemplate < Base include Helpers::InsertCommand, diff --git a/devops-service/db/mongo/models/stack/stack_base.rb b/devops-service/db/mongo/models/stack/stack_base.rb index ca32d2b..99d13ec 100644 --- a/devops-service/db/mongo/models/stack/stack_base.rb +++ b/devops-service/db/mongo/models/stack/stack_base.rb @@ -28,7 +28,7 @@ module Devops self.parameters = attrs['parameters'] self.details = attrs['details'] self.owner = attrs['owner'] - self.run_list = attrs['run_list'] + self.run_list = attrs['run_list'] || [] self end @@ -46,9 +46,9 @@ module Devops } end - def create_stack_in_cloud! + def create_stack_in_cloud! out begin - self.cloud_stack_id = provider_instance.create_stack(self) + provider_instance.create_stack(self, out) rescue ProviderErrors::NameConflict raise InvalidRecord.new "Duplicate key error: stack with name '#{id}' already exists in cloud" end @@ -93,9 +93,9 @@ module Devops # - id (String) # - deploy_env (String) # - stack_template (String) - def create(attrs) + def create(attrs, out) model = new(attrs) - model.create_stack_in_cloud! + model.create_stack_in_cloud!(out) model.sync_details! model end diff --git a/devops-service/db/mongo/models/stack/stack_factory.rb b/devops-service/db/mongo/models/stack/stack_factory.rb index be0e0fa..4c408f5 100644 --- a/devops-service/db/mongo/models/stack/stack_factory.rb +++ b/devops-service/db/mongo/models/stack/stack_factory.rb @@ -6,8 +6,8 @@ module Devops module Model class StackFactory - def self.create(provider, attrs) - get_class(provider).create(attrs) + def self.create(provider, attrs, out) + get_class(provider).create(attrs, out) end def self.build_from_bson(provider, attrs) diff --git a/devops-service/db/mongo/models/stack_template/stack_template_factory.rb b/devops-service/db/mongo/models/stack_template/stack_template_factory.rb index 15414d8..bdc579c 100644 --- a/devops-service/db/mongo/models/stack_template/stack_template_factory.rb +++ b/devops-service/db/mongo/models/stack_template/stack_template_factory.rb @@ -7,7 +7,9 @@ module Devops class StackTemplateFactory def self.create(provider, attrs) - get_class(provider).create(attrs) + attrs['id'] = "#{provider}_stack_template_#{Time.new.to_i}" + attrs['provider'] = provider + st = get_class(provider).create(attrs) end def self.build_from_bson(provider, attrs) diff --git a/devops-service/db/mongo/mongo_connector.rb b/devops-service/db/mongo/mongo_connector.rb index 57bd3db..21fc251 100644 --- a/devops-service/db/mongo/mongo_connector.rb +++ b/devops-service/db/mongo/mongo_connector.rb @@ -17,7 +17,7 @@ class MongoConnector [:available_images, :add_available_images, :delete_available_images] => :filters_connector, [:project, :projects_all, :projects, :project_names_with_envs, :projects_by_image, :projects_by_user, :project_insert, :project_update, - :project_delete, :is_project_exists?, :check_project_auth, :set_project_run_list, :set_project_env_run_list] => :projects_connector, + :project_delete, :is_project_exists?, :check_project_auth, :set_project_run_list, :set_project_env_run_list, :add_deploy_env_to_project] => :projects_connector, [:project_templates, :project_template_insert, :project_template_update, :project_template_delete] => :projects_templates_connector, [:servers_find, :servers, :stack_servers, :servers_by_names, :server_by_instance_id, diff --git a/devops-service/providers/openstack.rb b/devops-service/providers/openstack.rb index e0be192..bda77ea 100644 --- a/devops-service/providers/openstack.rb +++ b/devops-service/providers/openstack.rb @@ -207,15 +207,27 @@ module Provider 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 = orchestration.create_stack( stack_name: stack.name, template: stack.template_body, -# tenant_id: connection_options[:openstack_tenant], - parameters: stack.parameters + tenant_id: connection_options[:openstack_tenant], + parameters: stack.parameters || {} ) stack.id = response[:body]['stack']['id'] 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 @@ -236,6 +248,10 @@ module Provider 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 = {} @@ -262,7 +278,7 @@ module Provider end def fog_stack(stack) - orchestration.stacks.get(stack.id, stack.cloud_stack_id) + orchestration.stacks.get(stack.name, stack.id) end end diff --git a/devops-service/workers/stack_bootstrap_worker.rb b/devops-service/workers/stack_bootstrap_worker.rb index e97f7a2..3a6f44d 100644 --- a/devops-service/workers/stack_bootstrap_worker.rb +++ b/devops-service/workers/stack_bootstrap_worker.rb @@ -12,48 +12,47 @@ class StackBootstrapWorker < Worker # :stack_id def perform(options) call(options['config'], options['provider'], options['dir']) do |provider, out, file| - save_report(mongo, stack, file) - stack = Model::StackFactory.create(options['provider'], options['stack_attributes']) - stack.owner = options['owner'] + attrs = options['stack_attributes'] mongo = ::Devops::Db.connector + report = ::Devops::Model::Report.new( + "file" => file, + "_id" => jid, + "created_by" => attrs['owner'], + "project" => attrs["project"], + "deploy_env" => attrs["deploy_env"], + "type" => ::Devops::Model::Report::STACK_TYPE + ) + mongo.save_report(report) + + stack = Devops::Model::StackFactory.create(options['provider'], options['stack_attributes'], out) +# stack.owner = attrs['owner'] mongo.stack_insert(stack) sync_bootstrap_proc.call(out, stack, mongo) servers = persist_stack_servers!(stack, provider) - statuses = servers.map do |s| - Devops::Executor::ServerExecutor.new(s, out).two_phase_bootstrap({}) + unless options['stack_attributes']['without_bootstrap'] + statuses = servers.map do |s| + Devops::Executor::ServerExecutor.new(s, out).two_phase_bootstrap({}) + end end end end private - def save_report(mongo, stack, file) - report = ::Devops::Model::Report.new( - "file" => file, - "_id" => jid, - "created_by" => stack.owner, - "project" => stack.project, - "deploy_env" => stack.deploy_env, - "type" => ::Devops::Model::Report::STACK_TYPE - ) - mongo.save_report(report) - end - def persist_stack_servers!(stack, provider) mongo = ::Devops::Db.connector project = mongo.project(stack.project) deploy_env = project.deploy_env(stack.deploy_env) - stack.resources.map do |resource| - extended_info = stack.resource(resource.resource_name) + provider.stack_servers(stack).map do |extended_info | server_attrs = { 'provider' => provider.name, 'project' => project.id, 'deploy_env' => deploy_env.identifier, 'remote_user' => mongo.image(deploy_env.image).remote_user, 'key' => extended_info.key_name || provider.ssh_key, - 'id' => extended_info.id, + '_id' => extended_info.id, 'chef_node_name' => extended_info.name, 'private_ip' => extended_info.addresses.values.first.first['addr'], 'created_by' => stack.owner,