From 3c8f5258d08db9d63b3768050a42a30218c37004 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Mon, 13 Jul 2015 19:55:41 +0400 Subject: [PATCH 01/10] add possibility to stub only selected providers --- devops-service/app/devops-api2.rb | 2 +- devops-service/config.rb | 5 ++++- devops-service/lib/stubber.rb | 10 ++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/devops-service/app/devops-api2.rb b/devops-service/app/devops-api2.rb index 0337734..7635d4c 100644 --- a/devops-service/app/devops-api2.rb +++ b/devops-service/app/devops-api2.rb @@ -39,7 +39,7 @@ module Devops Devops::Api2.settings.mongo.create_root_user ::Provider::ProviderFactory.init(config) - Stubber.stub_providers! if config[:stub_classes] + Stubber.stub_providers!(config[:stub_providers]) end def routes diff --git a/devops-service/config.rb b/devops-service/config.rb index 5a42369..5b07675 100644 --- a/devops-service/config.rb +++ b/devops-service/config.rb @@ -40,4 +40,7 @@ config[:static_ssh_key] = "ssh_key" # or nil config[:static_certificate] = "/path/to/.ssh/static.pem" config[:debug] = true -config[:stub_classes] = true \ No newline at end of file + +# set it to :all or [:ec2] to stub calls to selected providers +# or to false to disable stubbing +config[:stub_providers] = false \ No newline at end of file diff --git a/devops-service/lib/stubber.rb b/devops-service/lib/stubber.rb index 18b530f..217ef91 100644 --- a/devops-service/lib/stubber.rb +++ b/devops-service/lib/stubber.rb @@ -1,5 +1,11 @@ module Stubber - def self.stub_providers! - Dir["tests/stubs/providers/*.rb"].each {|file| require file } + def self.stub_providers!(providers) + return unless providers + + providers = [:ec2, :openstack] if providers == :all + providers.each do |provider| + next unless [:ec2, :openstack].include?(provider) + require "tests/stubs/providers/#{provider}.rb" + end end end From a72fc782a317076329c38b7ebaf78aa8a0be631f Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Mon, 13 Jul 2015 21:26:13 +0400 Subject: [PATCH 02/10] current progress --- .../db/mongo/models/stack/stack_base.rb | 15 +++------ .../lib/stack_template_presets/base.rb | 32 +++++++++++++++---- devops-service/providers/openstack.rb | 6 ++-- .../routes/v2.0/handlers/stack_template.rb | 2 +- .../v2.0/handlers/stack_template_preset.rb | 1 + 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/devops-service/db/mongo/models/stack/stack_base.rb b/devops-service/db/mongo/models/stack/stack_base.rb index dbcc6c2..a961002 100644 --- a/devops-service/db/mongo/models/stack/stack_base.rb +++ b/devops-service/db/mongo/models/stack/stack_base.rb @@ -2,14 +2,13 @@ module Devops module Model class StackBase < MongoModel - attr_accessor :id, :project, :deploy_env, :stack_template, :cloud_stack_id, :provider, :parameters, :template_body + attr_accessor :id, :project, :deploy_env, :stack_template, :cloud_stack_id, :provider, :parameters types id: {type: String, empty: false}, provider: {type: String, empty: false}, - project: {type: String, empty: true}, - deploy_env: {type: String, empty: true}, - stack_template: {type: String, empty: true}, - template_body: {type: String, empty: true} + project: {type: String, nil: true}, + deploy_env: {type: String, nil: true}, + stack_template: {type: String, empty: false} # cloud_stack_id: {type: String, empty: true} # TODO: add parameters Hash @@ -19,7 +18,6 @@ module Devops self.project = attrs['project'] self.deploy_env = attrs['deploy_env'] self.stack_template = attrs['stack_template'] - self.template_body = attrs['template_body'] # self.cloud_stack_id = attrs['cloud_stack_id'] self.parameters = attrs['parameters'] self @@ -61,11 +59,8 @@ module Devops raise 'override me' end - # if not set in constructor, assume stack was created via stack_template. - # It is need to support presets. - # TODO: refactore it. def template_body - @template_body ||= Devops::Api2.settings.mongo.stack_template(stack_template).template_body + Devops::Api2.settings.mongo.stack_template(stack_template).template_body end end diff --git a/devops-service/lib/stack_template_presets/base.rb b/devops-service/lib/stack_template_presets/base.rb index d637121..aa692f7 100644 --- a/devops-service/lib/stack_template_presets/base.rb +++ b/devops-service/lib/stack_template_presets/base.rb @@ -10,20 +10,20 @@ module Devops end def to_hash - {id: id, template_preset_body: template_preset_body} + {id: id, template_body: template_body} end def create_stack_from_preset(provider, stack_id, parameters) - stack_attrs = { + find_or_create_stack_template!(provider) + Model::StackFactory.create(provider, { 'id' => stack_id, 'provider' => provider, 'parameters' => parameters, - 'template_body' => template_preset_body - } - Model::StackFactory.create(provider, stack_attrs) + 'stack_template' => stack_template_name(provider) + }) end - def template_preset_body + def template_body file_name = File.join("lib/stack_template_presets/#{id}.#{template_file_extension}") File.read(file_name) end @@ -33,6 +33,26 @@ module Devops :json end + private + + def find_or_create_stack_template!(provider) + name = stack_template_name(provider) + begin + Devops::Api2.settings.mongo.stack_template(name) + rescue RecordNotFound + template = Model::StackTemplateFactory.create(provider, { + 'id' => name, + 'provider' => provider, + 'template_body' => template_body + }) + Devops::Api2.settings.mongo.stack_template_insert(template) + end + end + + def stack_template_name(provider) + "#{id}_#{provider}_preset" + end + end end end \ No newline at end of file diff --git a/devops-service/providers/openstack.rb b/devops-service/providers/openstack.rb index b3f92f7..5a10594 100644 --- a/devops-service/providers/openstack.rb +++ b/devops-service/providers/openstack.rb @@ -193,11 +193,13 @@ module Provider def create_stack(stack) begin - response = orchestration.create_stack(stack.id, { + response = orchestration.create_stack( + stack_name: stack.id, template: stack.template_body, tenant_id: connection_options[:openstack_tenant], parameters: stack.parameters - }) + ) + # byebug response[:body]['stack']['id'] rescue Excon::Errors::Conflict => e raise ProviderErrors::NameConflict diff --git a/devops-service/routes/v2.0/handlers/stack_template.rb b/devops-service/routes/v2.0/handlers/stack_template.rb index 5a690bb..ae8e799 100644 --- a/devops-service/routes/v2.0/handlers/stack_template.rb +++ b/devops-service/routes/v2.0/handlers/stack_template.rb @@ -28,8 +28,8 @@ module Devops attrs = create_object_from_json_body template_model = Model::StackTemplateFactory.create(attrs['provider'], attrs) - settings.mongo.stack_template_insert(template_model) + create_response 'Created', template_model.to_hash, 201 } end diff --git a/devops-service/routes/v2.0/handlers/stack_template_preset.rb b/devops-service/routes/v2.0/handlers/stack_template_preset.rb index 766e23b..1d71146 100644 --- a/devops-service/routes/v2.0/handlers/stack_template_preset.rb +++ b/devops-service/routes/v2.0/handlers/stack_template_preset.rb @@ -31,6 +31,7 @@ module Devops preset = Devops::StackTemplatePresetsFactory.get(attrs.fetch('id')) stack = preset.create_stack_from_preset(provider, stack_id, parameters) + settings.mongo.stack_insert(stack) create_response 'Created', stack.to_hash, 201 } From 7ac62a2a36a263a16bdc0caf3bf1cb43db9e5303 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Tue, 14 Jul 2015 17:51:40 +0400 Subject: [PATCH 03/10] add sync method to stack --- .../lib/devops-client/handler/stack.rb | 14 +++- .../devops-client/options/stack_options.rb | 3 +- .../lib/devops-client/output/stack.rb | 2 +- devops-client/locales/en.yml | 1 + .../connectors/helpers/update_command.rb | 5 +- devops-service/db/mongo/connectors/stack.rb | 3 +- .../db/mongo/models/stack/stack_base.rb | 73 ++++++++++++------- .../db/mongo/models/stack/stack_ec2.rb | 7 +- .../db/mongo/models/stack/stack_openstack.rb | 16 +--- devops-service/db/mongo/mongo_connector.rb | 2 +- devops-service/providers/openstack.rb | 4 + devops-service/routes/v2.0/handlers/stack.rb | 12 +++ devops-service/routes/v2.0/stack.rb | 2 + devops-service/tests/stubs/providers/ec2.rb | 8 ++ .../00_list/stack_template_preset.feature.erb | 4 +- 15 files changed, 99 insertions(+), 57 deletions(-) diff --git a/devops-client/lib/devops-client/handler/stack.rb b/devops-client/lib/devops-client/handler/stack.rb index ef16309..8f88582 100644 --- a/devops-client/lib/devops-client/handler/stack.rb +++ b/devops-client/lib/devops-client/handler/stack.rb @@ -13,7 +13,6 @@ class Stack < Handler end def handle - current_command = ARGV[1].to_sym @options, @args = @options_parser.parse_options_for!(current_command) case current_command when :list @@ -26,6 +25,9 @@ class Stack < Handler create_handler when :delete delete_handler + when :sync_details + sync_handler + output end end @@ -63,6 +65,16 @@ class Stack < Handler @show = get "/stack/#{stack_id}" end + def sync_handler + stack_id = @args[2] + r = inspect_parameters(@options_parser.sync_details_params, stack_id) + unless r.nil? + @options_parser.invalid_sync_command + abort(r) + end + @show = post "/stack/#{stack_id}/sync_details" + end + def delete_handler stack_id = @args[2] r = inspect_parameters(@options_parser.delete_params, stack_id) diff --git a/devops-client/lib/devops-client/options/stack_options.rb b/devops-client/lib/devops-client/options/stack_options.rb index f824002..ce968ce 100644 --- a/devops-client/lib/devops-client/options/stack_options.rb +++ b/devops-client/lib/devops-client/options/stack_options.rb @@ -2,7 +2,7 @@ require "devops-client/options/common_options" class StackOptions < CommonOptions - commands :create, :delete, :list, :show + commands :create, :delete, :list, :show, :sync_details def initialize args, def_options super(args, def_options) @@ -11,6 +11,7 @@ class StackOptions < CommonOptions self.list_params = ["[provider]", "[ec2|openstack]"] self.show_params = ["STACK"] self.delete_params = ["STACK"] + self.sync_details_params = ["STACK"] end def create_options diff --git a/devops-client/lib/devops-client/output/stack.rb b/devops-client/lib/devops-client/output/stack.rb index e87d5ec..b38ad59 100644 --- a/devops-client/lib/devops-client/output/stack.rb +++ b/devops-client/lib/devops-client/output/stack.rb @@ -37,7 +37,7 @@ module Output end def create_show - headers_and_rows([@data], %w(id deploy_env stack_template cloud_stack_id)) + headers_and_rows([@data], %w(id deploy_env stack_template cloud_stack_id details)) end end diff --git a/devops-client/locales/en.yml b/devops-client/locales/en.yml index f121224..502343e 100644 --- a/devops-client/locales/en.yml +++ b/devops-client/locales/en.yml @@ -196,6 +196,7 @@ en: template_preset_body: "Template preset body" stack_template: "Stack Template" cloud_stack_id: "Cloud Stack id" + details: "Details are not displayed in table view" title: flavor: list: "Flavors" diff --git a/devops-service/db/mongo/connectors/helpers/update_command.rb b/devops-service/db/mongo/connectors/helpers/update_command.rb index ac5d3bb..b661196 100644 --- a/devops-service/db/mongo/connectors/helpers/update_command.rb +++ b/devops-service/db/mongo/connectors/helpers/update_command.rb @@ -4,9 +4,8 @@ module Connectors module Helpers module UpdateCommand - # when included, this module adds method #update and alias for it. - # Alias name depends on base class name. - # We need this alias to forward methods from MongoConnector to resources connectors. + # this module adds methods #update and "#{resource_name}_update" (they are synonyms). + # We need second method name to forward methods from MongoConnector to resources connectors. def self.included(base) resource_name = StringHelper.underscore_class(base) diff --git a/devops-service/db/mongo/connectors/stack.rb b/devops-service/db/mongo/connectors/stack.rb index d2a7cac..d051670 100644 --- a/devops-service/db/mongo/connectors/stack.rb +++ b/devops-service/db/mongo/connectors/stack.rb @@ -3,7 +3,8 @@ module Connectors include Helpers::InsertCommand, Helpers::ShowCommand, Helpers::ListCommand, - Helpers::DeleteCommand + Helpers::DeleteCommand, + Helpers::UpdateCommand def initialize(db) self.collection = db.collection('stacks') diff --git a/devops-service/db/mongo/models/stack/stack_base.rb b/devops-service/db/mongo/models/stack/stack_base.rb index a961002..2926ab3 100644 --- a/devops-service/db/mongo/models/stack/stack_base.rb +++ b/devops-service/db/mongo/models/stack/stack_base.rb @@ -2,24 +2,27 @@ module Devops module Model class StackBase < MongoModel - attr_accessor :id, :project, :deploy_env, :stack_template, :cloud_stack_id, :provider, :parameters + attr_accessor :id, :project, :deploy_env, :stack_template, + :cloud_stack_id, :provider, :parameters, :details types id: {type: String, empty: false}, provider: {type: String, empty: false}, project: {type: String, nil: true}, deploy_env: {type: String, nil: true}, - stack_template: {type: String, empty: false} - # cloud_stack_id: {type: String, empty: true} - # TODO: add parameters Hash + stack_template: {type: String, empty: false}, + cloud_stack_id: {type: String, nil: true} + # details: {type: String, nil: true} def initialize attrs={} + self.provider = self.class.provider + self.id = attrs['id'] - self.provider = attrs['provider'] self.project = attrs['project'] self.deploy_env = attrs['deploy_env'] self.stack_template = attrs['stack_template'] - # self.cloud_stack_id = attrs['cloud_stack_id'] + self.cloud_stack_id = attrs['cloud_stack_id'] self.parameters = attrs['parameters'] + self.details = attrs['details'] self end @@ -30,39 +33,57 @@ module Devops deploy_env: deploy_env, stack_template: stack_template, cloud_stack_id: cloud_stack_id, - parameters: parameters + parameters: parameters, + details: details } end - - # attrs should include: - # - id (String) - # - provider (String) - # - deploy_env (String) - # - stack_template (String) - def self.create(attrs) - model = new(attrs) - model.create_stack_in_cloud! - model - end - - def self.build_from_bson(attrs) - attrs['id'] = attrs["_id"] - self.new(attrs) - end - def create_stack_in_cloud! - raise 'override me' + begin + self.cloud_stack_id = provider_class.create_stack(self) + rescue ProviderErrors::NameConflict + raise InvalidRecord.new "Duplicate key error: stack with name '#{id}' already exists in cloud" + end end def delete_stack_in_cloud! - raise 'override me' + provider_class.delete_stack(self) + end + + def sync_details! + details = provider_class.stack_details(self) + self.details = details#.to_json end def template_body Devops::Api2.settings.mongo.stack_template(stack_template).template_body end + class << self + attr_accessor :provider + + # attrs should include: + # - id (String) + # - deploy_env (String) + # - stack_template (String) + def create(attrs) + model = new(attrs) + model.create_stack_in_cloud! + model + end + + def build_from_bson(attrs) + attrs['id'] = attrs["_id"] + self.new(attrs) + end + end + + private + + def provider_class + Provider::ProviderFactory.get(provider) + end + end end end diff --git a/devops-service/db/mongo/models/stack/stack_ec2.rb b/devops-service/db/mongo/models/stack/stack_ec2.rb index bd00161..693b9d2 100644 --- a/devops-service/db/mongo/models/stack/stack_ec2.rb +++ b/devops-service/db/mongo/models/stack/stack_ec2.rb @@ -1,12 +1,7 @@ module Devops module Model class StackEc2 < StackBase - - def create_stack_in_cloud! - # create stack in AWS - self.cloud_stack_id = 'arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83' - end - + self.provider = 'ec2' end end end diff --git a/devops-service/db/mongo/models/stack/stack_openstack.rb b/devops-service/db/mongo/models/stack/stack_openstack.rb index 83151ef..68bf213 100644 --- a/devops-service/db/mongo/models/stack/stack_openstack.rb +++ b/devops-service/db/mongo/models/stack/stack_openstack.rb @@ -1,21 +1,7 @@ module Devops module Model class StackOpenstack < StackBase - - def create_stack_in_cloud! - begin - provider = Provider::ProviderFactory.get('openstack') - self.cloud_stack_id = provider.create_stack(self) - rescue ProviderErrors::NameConflict - raise InvalidRecord.new "Duplicate key error: stack with name '#{self.id}' already exists in cloud" - end - end - - def delete_stack_in_cloud! - provider = Provider::ProviderFactory.get('openstack') - provider.delete_stack(self) - end - + self.provider = 'openstack' end end end diff --git a/devops-service/db/mongo/mongo_connector.rb b/devops-service/db/mongo/mongo_connector.rb index 93fb641..b1434bd 100644 --- a/devops-service/db/mongo/mongo_connector.rb +++ b/devops-service/db/mongo/mongo_connector.rb @@ -13,7 +13,7 @@ class MongoConnector delegate( [:images, :image, :image_insert, :image_delete, :image_update] => :images_connector, [:stack_templates, :stack_template, :stack_template_insert, :stack_template_delete] => :stack_templates_connector, - [:stacks, :stack, :stack_insert, :stack_delete] => :stacks_connector, + [:stacks, :stack, :stack_insert, :stack_delete, :stack_update] => :stacks_connector, [: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, diff --git a/devops-service/providers/openstack.rb b/devops-service/providers/openstack.rb index 5a10594..ed65a9f 100644 --- a/devops-service/providers/openstack.rb +++ b/devops-service/providers/openstack.rb @@ -210,6 +210,10 @@ module Provider orchestration.delete_stack(stack.id, stack.cloud_stack_id) end + def stack_details(stack) + orchestration.show_stack_details(stack.id, stack.cloud_stack_id).data + end + private def convert_groups list res = {} diff --git a/devops-service/routes/v2.0/handlers/stack.rb b/devops-service/routes/v2.0/handlers/stack.rb index 1e1d794..f70978b 100644 --- a/devops-service/routes/v2.0/handlers/stack.rb +++ b/devops-service/routes/v2.0/handlers/stack.rb @@ -54,6 +54,18 @@ module Devops } end + def self.sync_details + lambda { + check_privileges("stack", "w") + + stack = settings.mongo.stack(params[:stack_id]) + stack.sync_details! + settings.mongo.stack_update(stack) + + json stack.to_hash + } + end + end end end diff --git a/devops-service/routes/v2.0/stack.rb b/devops-service/routes/v2.0/stack.rb index 70c3364..309f61a 100644 --- a/devops-service/routes/v2.0/stack.rb +++ b/devops-service/routes/v2.0/stack.rb @@ -14,6 +14,8 @@ module Devops app.post_with_headers "/stack", :headers => [:accept], &Devops::Version2_0::Handler::Stack.create_stack + app.post_with_headers "/stack/:stack_id/sync_details", :headers => [:accept], &Devops::Version2_0::Handler::Stack.sync_details + hash = {} hash['GET'] = Devops::Version2_0::Handler::Stack.get_stack diff --git a/devops-service/tests/stubs/providers/ec2.rb b/devops-service/tests/stubs/providers/ec2.rb index a1fd0be..0459307 100644 --- a/devops-service/tests/stubs/providers/ec2.rb +++ b/devops-service/tests/stubs/providers/ec2.rb @@ -62,4 +62,12 @@ class Provider::Ec2 ] end + def create_stack(stack) + 'arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83' + end + + def delete_stack(stack) + true + end + end \ No newline at end of file diff --git a/devops-service/tests/templates/api_v2/00_list/stack_template_preset.feature.erb b/devops-service/tests/templates/api_v2/00_list/stack_template_preset.feature.erb index 823f006..52e63fb 100644 --- a/devops-service/tests/templates/api_v2/00_list/stack_template_preset.feature.erb +++ b/devops-service/tests/templates/api_v2/00_list/stack_template_preset.feature.erb @@ -11,7 +11,7 @@ Feature: stack template preset list [ { "id": "test", - "template_preset_body": "long body" + "template_body": "long body" } ] """ @@ -23,6 +23,6 @@ Feature: stack template preset list And response should be JSON object like: """ { - "id": "postgres_cluster", "template_preset_body": "long body" + "id": "postgres_cluster", "template_body": "long body" } """ \ No newline at end of file From e11788afb74f5e425f3c7e336db9aa0ff0f7ffa9 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Wed, 15 Jul 2015 17:25:06 +0400 Subject: [PATCH 04/10] autoupdate stack template preset body --- .../lib/devops-client/output/stack.rb | 5 +-- devops-client/locales/en.yml | 2 +- .../db/mongo/connectors/stack_template.rb | 3 +- .../db/mongo/models/stack/stack_base.rb | 3 +- .../db/mongo/models/stack/stack_openstack.rb | 4 +++ devops-service/db/mongo/mongo_connector.rb | 2 +- .../lib/stack_template_presets/base.rb | 33 ++++++++++++------- .../postgres_cluster.yml | 3 +- devops-service/providers/openstack.rb | 2 +- 9 files changed, 38 insertions(+), 19 deletions(-) diff --git a/devops-client/lib/devops-client/output/stack.rb b/devops-client/lib/devops-client/output/stack.rb index b38ad59..2cf9e09 100644 --- a/devops-client/lib/devops-client/output/stack.rb +++ b/devops-client/lib/devops-client/output/stack.rb @@ -10,6 +10,7 @@ module Output title = I18n.t("output.title.stack.list") headers, rows = create_list else + puts 'Details are not displayed in table view' title = I18n.t("output.title.stack.show", id: @data["id"]) headers, rows = create_show end @@ -30,14 +31,14 @@ module Output def create_list abort(I18n.t("output.not_found.stack.list")) if @data.empty? - fields_to_output = %w(id deploy_env stack_template) + fields_to_output = %w(id deploy_env stack_template cloud_stack_id stack_status) fields_to_output << 'provider' unless provider_given? headers_and_rows(@data, fields_to_output) end def create_show - headers_and_rows([@data], %w(id deploy_env stack_template cloud_stack_id details)) + headers_and_rows([@data], %w(id deploy_env stack_template cloud_stack_id stack_status)) end end diff --git a/devops-client/locales/en.yml b/devops-client/locales/en.yml index 502343e..a13f9cb 100644 --- a/devops-client/locales/en.yml +++ b/devops-client/locales/en.yml @@ -196,7 +196,7 @@ en: template_preset_body: "Template preset body" stack_template: "Stack Template" cloud_stack_id: "Cloud Stack id" - details: "Details are not displayed in table view" + stack_status: Stack status title: flavor: list: "Flavors" diff --git a/devops-service/db/mongo/connectors/stack_template.rb b/devops-service/db/mongo/connectors/stack_template.rb index dc0b2f0..d1202b0 100644 --- a/devops-service/db/mongo/connectors/stack_template.rb +++ b/devops-service/db/mongo/connectors/stack_template.rb @@ -3,7 +3,8 @@ module Connectors include Helpers::InsertCommand, Helpers::ShowCommand, Helpers::ListCommand, - Helpers::DeleteCommand + Helpers::DeleteCommand, + Helpers::UpdateCommand def initialize(db) self.collection = db.collection('stack_templates') diff --git a/devops-service/db/mongo/models/stack/stack_base.rb b/devops-service/db/mongo/models/stack/stack_base.rb index 2926ab3..e2b9189 100644 --- a/devops-service/db/mongo/models/stack/stack_base.rb +++ b/devops-service/db/mongo/models/stack/stack_base.rb @@ -34,7 +34,8 @@ module Devops stack_template: stack_template, cloud_stack_id: cloud_stack_id, parameters: parameters, - details: details + details: details, + stack_status: stack_status } end diff --git a/devops-service/db/mongo/models/stack/stack_openstack.rb b/devops-service/db/mongo/models/stack/stack_openstack.rb index 68bf213..a8e5bfd 100644 --- a/devops-service/db/mongo/models/stack/stack_openstack.rb +++ b/devops-service/db/mongo/models/stack/stack_openstack.rb @@ -2,6 +2,10 @@ module Devops module Model class StackOpenstack < StackBase self.provider = 'openstack' + + def stack_status + details[:body]['stack']['stack_status'] if details + end end end end diff --git a/devops-service/db/mongo/mongo_connector.rb b/devops-service/db/mongo/mongo_connector.rb index b1434bd..c92c2f5 100644 --- a/devops-service/db/mongo/mongo_connector.rb +++ b/devops-service/db/mongo/mongo_connector.rb @@ -12,7 +12,7 @@ class MongoConnector delegate( [:images, :image, :image_insert, :image_delete, :image_update] => :images_connector, - [:stack_templates, :stack_template, :stack_template_insert, :stack_template_delete] => :stack_templates_connector, + [:stack_templates, :stack_template, :stack_template_insert, :stack_template_delete, :stack_template_update] => :stack_templates_connector, [:stacks, :stack, :stack_insert, :stack_delete, :stack_update] => :stacks_connector, [:available_images, :add_available_images, :delete_available_images] => :filters_connector, [:project, :projects_all, :projects, :project_names_with_envs, diff --git a/devops-service/lib/stack_template_presets/base.rb b/devops-service/lib/stack_template_presets/base.rb index aa692f7..3914b62 100644 --- a/devops-service/lib/stack_template_presets/base.rb +++ b/devops-service/lib/stack_template_presets/base.rb @@ -14,18 +14,18 @@ module Devops end def create_stack_from_preset(provider, stack_id, parameters) - find_or_create_stack_template!(provider) + template_name = find_or_create_stack_template!(provider) + puts "Using #{template_name} stack_template to create new stack" Model::StackFactory.create(provider, { 'id' => stack_id, 'provider' => provider, 'parameters' => parameters, - 'stack_template' => stack_template_name(provider) + 'stack_template' => template_name }) end def template_body - file_name = File.join("lib/stack_template_presets/#{id}.#{template_file_extension}") - File.read(file_name) + @template_body ||= File.read("lib/stack_template_presets/#{id}.#{template_file_extension}") end # some templates may be YAML files @@ -38,21 +38,32 @@ module Devops def find_or_create_stack_template!(provider) name = stack_template_name(provider) begin - Devops::Api2.settings.mongo.stack_template(name) + stack_template = Devops::Api2.settings.mongo.stack_template(name) + update_stack_template(stack_template) if stack_template.template_body != template_body rescue RecordNotFound - template = Model::StackTemplateFactory.create(provider, { - 'id' => name, - 'provider' => provider, - 'template_body' => template_body - }) - Devops::Api2.settings.mongo.stack_template_insert(template) + create_stack_template(provider) end + name end def stack_template_name(provider) "#{id}_#{provider}_preset" end + def create_stack_template(provider) + stack_template = Model::StackTemplateFactory.create(provider, { + 'id' => stack_template_name(provider), + 'provider' => provider, + 'template_body' => template_body + }) + Devops::Api2.settings.mongo.stack_template_insert(stack_template) + end + + def update_stack_template(stack_template) + stack_template.template_body = template_body + Devops::Api2.settings.mongo.stack_template_update(stack_template) + end + end end end \ No newline at end of file diff --git a/devops-service/lib/stack_template_presets/postgres_cluster.yml b/devops-service/lib/stack_template_presets/postgres_cluster.yml index 7f97c80..e023231 100644 --- a/devops-service/lib/stack_template_presets/postgres_cluster.yml +++ b/devops-service/lib/stack_template_presets/postgres_cluster.yml @@ -14,4 +14,5 @@ resources: properties: key_name: { get_param: key_name } image: 227f4be7-be1c-498d-ab88-54f8b5df249f - flavor: m1.small \ No newline at end of file + flavor: m1.small + network: devops-net-1 \ No newline at end of file diff --git a/devops-service/providers/openstack.rb b/devops-service/providers/openstack.rb index ed65a9f..e96df6d 100644 --- a/devops-service/providers/openstack.rb +++ b/devops-service/providers/openstack.rb @@ -199,7 +199,6 @@ module Provider tenant_id: connection_options[:openstack_tenant], parameters: stack.parameters ) - # byebug response[:body]['stack']['id'] rescue Excon::Errors::Conflict => e raise ProviderErrors::NameConflict @@ -211,6 +210,7 @@ module Provider end def stack_details(stack) + puts "Fetching information about stack #{stack.id}/#{stack.cloud_stack_id}" orchestration.show_stack_details(stack.id, stack.cloud_stack_id).data end From fb5cdea4b290d918eb828665b3af0ad751c53b89 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Wed, 15 Jul 2015 18:47:59 +0400 Subject: [PATCH 05/10] change preset params to make it createable --- .../lib/stack_template_presets/postgres_cluster.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/devops-service/lib/stack_template_presets/postgres_cluster.yml b/devops-service/lib/stack_template_presets/postgres_cluster.yml index e023231..6b8bc1b 100644 --- a/devops-service/lib/stack_template_presets/postgres_cluster.yml +++ b/devops-service/lib/stack_template_presets/postgres_cluster.yml @@ -13,6 +13,7 @@ resources: type: OS::Nova::Server properties: key_name: { get_param: key_name } - image: 227f4be7-be1c-498d-ab88-54f8b5df249f - flavor: m1.small - network: devops-net-1 \ No newline at end of file + image: 5f4020a1-b6ab-47e4-a0ed-de4324a17c3a + flavor: m1.micro + networks: + - network: devops-net-1 \ No newline at end of file From 9aad1253fef2dde24783b3f5a3d8417463eda678 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Wed, 15 Jul 2015 19:37:27 +0400 Subject: [PATCH 06/10] add ability to watch stack resources --- .../handler/helpers/outputtable.rb | 4 ++-- .../lib/devops-client/handler/stack.rb | 17 +++++++++++++++-- .../lib/devops-client/options/stack_options.rb | 5 +++-- devops-client/lib/devops-client/output/base.rb | 5 +++-- .../db/mongo/models/stack/stack_base.rb | 7 +++++-- .../db/mongo/models/stack/stack_openstack.rb | 2 +- devops-service/providers/openstack.rb | 13 ++++++++++--- devops-service/routes/v2.0/handlers/stack.rb | 8 ++++++++ devops-service/routes/v2.0/stack.rb | 2 ++ 9 files changed, 49 insertions(+), 14 deletions(-) diff --git a/devops-client/lib/devops-client/handler/helpers/outputtable.rb b/devops-client/lib/devops-client/handler/helpers/outputtable.rb index 9414054..8cb52b1 100644 --- a/devops-client/lib/devops-client/handler/helpers/outputtable.rb +++ b/devops-client/lib/devops-client/handler/helpers/outputtable.rb @@ -13,8 +13,8 @@ module Outputtable @outputter ||= outputter_class.new(data_to_output, options, additional_output_options) end - def output - outputter.output + def output(preferred_format=nil) + outputter.output(preferred_format) end diff --git a/devops-client/lib/devops-client/handler/stack.rb b/devops-client/lib/devops-client/handler/stack.rb index 8f88582..782f958 100644 --- a/devops-client/lib/devops-client/handler/stack.rb +++ b/devops-client/lib/devops-client/handler/stack.rb @@ -25,9 +25,12 @@ class Stack < Handler create_handler when :delete delete_handler - when :sync_details + when :sync sync_handler output + when :resources + resources_handler + output('json') end end @@ -67,7 +70,7 @@ class Stack < Handler def sync_handler stack_id = @args[2] - r = inspect_parameters(@options_parser.sync_details_params, stack_id) + r = inspect_parameters(@options_parser.sync_params, stack_id) unless r.nil? @options_parser.invalid_sync_command abort(r) @@ -75,6 +78,16 @@ class Stack < Handler @show = post "/stack/#{stack_id}/sync_details" end + def resources_handler + stack_id = @args[2] + r = inspect_parameters(@options_parser.sync_params, stack_id) + unless r.nil? + @options_parser.invalid_sync_command + abort(r) + end + @list = get "/stack/#{stack_id}/resources" + end + def delete_handler stack_id = @args[2] r = inspect_parameters(@options_parser.delete_params, stack_id) diff --git a/devops-client/lib/devops-client/options/stack_options.rb b/devops-client/lib/devops-client/options/stack_options.rb index ce968ce..ac64fe7 100644 --- a/devops-client/lib/devops-client/options/stack_options.rb +++ b/devops-client/lib/devops-client/options/stack_options.rb @@ -2,7 +2,7 @@ require "devops-client/options/common_options" class StackOptions < CommonOptions - commands :create, :delete, :list, :show, :sync_details + commands :create, :delete, :list, :show, :sync, :resources def initialize args, def_options super(args, def_options) @@ -11,7 +11,8 @@ class StackOptions < CommonOptions self.list_params = ["[provider]", "[ec2|openstack]"] self.show_params = ["STACK"] self.delete_params = ["STACK"] - self.sync_details_params = ["STACK"] + self.sync_params = ["STACK"] + self.resources_params = ["STACK"] end def create_options diff --git a/devops-client/lib/devops-client/output/base.rb b/devops-client/lib/devops-client/output/base.rb index b7049bb..04a1a42 100644 --- a/devops-client/lib/devops-client/output/base.rb +++ b/devops-client/lib/devops-client/output/base.rb @@ -18,8 +18,9 @@ module Output @data, @options, @additional_options = data_to_output, command_line_options, additional_options end - def output - case options[:format] + def output(format = nil) + format ||= options[:format] + case format when CommonOptions::TABLE_FORMAT table when CommonOptions::JSON_FORMAT diff --git a/devops-service/db/mongo/models/stack/stack_base.rb b/devops-service/db/mongo/models/stack/stack_base.rb index e2b9189..1c4fd20 100644 --- a/devops-service/db/mongo/models/stack/stack_base.rb +++ b/devops-service/db/mongo/models/stack/stack_base.rb @@ -52,8 +52,11 @@ module Devops end def sync_details! - details = provider_class.stack_details(self) - self.details = details#.to_json + self.details = provider_class.stack_details(self) + end + + def resources + provider_class.stack_resources(self) end def template_body diff --git a/devops-service/db/mongo/models/stack/stack_openstack.rb b/devops-service/db/mongo/models/stack/stack_openstack.rb index a8e5bfd..62918ae 100644 --- a/devops-service/db/mongo/models/stack/stack_openstack.rb +++ b/devops-service/db/mongo/models/stack/stack_openstack.rb @@ -4,7 +4,7 @@ module Devops self.provider = 'openstack' def stack_status - details[:body]['stack']['stack_status'] if details + details[:stack_status] if details end end end diff --git a/devops-service/providers/openstack.rb b/devops-service/providers/openstack.rb index e96df6d..a5f74fb 100644 --- a/devops-service/providers/openstack.rb +++ b/devops-service/providers/openstack.rb @@ -206,12 +206,15 @@ module Provider end def delete_stack(stack) - orchestration.delete_stack(stack.id, stack.cloud_stack_id) + fog_stack(stack).destroy end def stack_details(stack) - puts "Fetching information about stack #{stack.id}/#{stack.cloud_stack_id}" - orchestration.show_stack_details(stack.id, stack.cloud_stack_id).data + fog_stack(stack).details.attributes + end + + def stack_resources(stack) + fog_stack(stack).resources end private @@ -239,5 +242,9 @@ module Provider @connection ||= Fog::Orchestration.new(connection_options) end + def fog_stack(stack) + orchestration.stacks.get(stack.id, stack.cloud_stack_id) + end + end end diff --git a/devops-service/routes/v2.0/handlers/stack.rb b/devops-service/routes/v2.0/handlers/stack.rb index f70978b..cc5b652 100644 --- a/devops-service/routes/v2.0/handlers/stack.rb +++ b/devops-service/routes/v2.0/handlers/stack.rb @@ -66,6 +66,14 @@ module Devops } end + def self.resources + lambda { + check_privileges("stack", "r") + stack = settings.mongo.stack(params[:stack_id]) + json stack.resources + } + end + end end end diff --git a/devops-service/routes/v2.0/stack.rb b/devops-service/routes/v2.0/stack.rb index 309f61a..1d866aa 100644 --- a/devops-service/routes/v2.0/stack.rb +++ b/devops-service/routes/v2.0/stack.rb @@ -16,6 +16,8 @@ module Devops app.post_with_headers "/stack/:stack_id/sync_details", :headers => [:accept], &Devops::Version2_0::Handler::Stack.sync_details + app.get_with_headers "/stack/:stack_id/resources", :headers => [:accept], &Devops::Version2_0::Handler::Stack.resources + hash = {} hash['GET'] = Devops::Version2_0::Handler::Stack.get_stack From 589fc6ff844a8b19b14cc0d6808bed263f057011 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Wed, 15 Jul 2015 20:21:23 +0400 Subject: [PATCH 07/10] rename stack_template_presets to stack_presets --- .../devops-client/handler/handler_factory.rb | 6 ++-- ...ack_template_preset.rb => stack_preset.rb} | 31 +++++++++-------- .../options/stack_preset_options.rb | 33 +++++++++++++++++++ .../options/stack_template_preset_options.rb | 33 ------------------- ...ack_template_preset.rb => stack_preset.rb} | 6 ++-- devops-client/locales/en.yml | 12 +++---- devops-service/app/devops-api2.rb | 4 +-- .../base.rb | 4 +-- .../factory.rb | 10 +++--- .../postgres_cluster.rb | 2 +- .../postgres_cluster.yml | 0 .../preset_not_found.rb | 0 ...ack_template_preset.rb => stack_preset.rb} | 18 +++++----- ...k_template_presets.rb => stack_presets.rb} | 14 ++++---- devops-service/tests/generate_tests.rb | 2 +- .../tests/stubs/providers/openstack.rb | 8 +++++ .../00_list/stack_template_preset.feature.erb | 6 ++-- 17 files changed, 98 insertions(+), 91 deletions(-) rename devops-client/lib/devops-client/handler/{stack_template_preset.rb => stack_preset.rb} (55%) create mode 100644 devops-client/lib/devops-client/options/stack_preset_options.rb delete mode 100644 devops-client/lib/devops-client/options/stack_template_preset_options.rb rename devops-client/lib/devops-client/output/{stack_template_preset.rb => stack_preset.rb} (77%) rename devops-service/lib/{stack_template_presets => stack_presets}/base.rb (93%) rename devops-service/lib/{stack_template_presets => stack_presets}/factory.rb (56%) rename devops-service/lib/{stack_template_presets => stack_presets}/postgres_cluster.rb (71%) rename devops-service/lib/{stack_template_presets => stack_presets}/postgres_cluster.yml (100%) rename devops-service/lib/{stack_template_presets => stack_presets}/preset_not_found.rb (100%) rename devops-service/routes/v2.0/handlers/{stack_template_preset.rb => stack_preset.rb} (56%) rename devops-service/routes/v2.0/{stack_template_presets.rb => stack_presets.rb} (65%) diff --git a/devops-client/lib/devops-client/handler/handler_factory.rb b/devops-client/lib/devops-client/handler/handler_factory.rb index e1f9d9c..c5b7898 100644 --- a/devops-client/lib/devops-client/handler/handler_factory.rb +++ b/devops-client/lib/devops-client/handler/handler_factory.rb @@ -47,9 +47,9 @@ class HandlerFactory when "stack_template" require "devops-client/handler/stack_template" StackTemplate - when "stack_template_preset" - require "devops-client/handler/stack_template_preset" - StackTemplatePreset + when "stack_preset" + require "devops-client/handler/stack_preset" + StackPreset when "stack" require "devops-client/handler/stack" Stack diff --git a/devops-client/lib/devops-client/handler/stack_template_preset.rb b/devops-client/lib/devops-client/handler/stack_preset.rb similarity index 55% rename from devops-client/lib/devops-client/handler/stack_template_preset.rb rename to devops-client/lib/devops-client/handler/stack_preset.rb index 674284e..427cdfe 100644 --- a/devops-client/lib/devops-client/handler/stack_template_preset.rb +++ b/devops-client/lib/devops-client/handler/stack_preset.rb @@ -1,15 +1,14 @@ require "devops-client/handler/handler" -require "devops-client/options/stack_template_preset_options" -require "devops-client/output/stack_template_preset" -# require 'devops-client/helpers/select_available' +require "devops-client/options/stack_preset_options" +require "devops-client/output/stack_preset" -class StackTemplatePreset < Handler +class StackPreset < Handler - output_with Output::StackTemplatePreset + output_with Output::StackPreset def initialize(host, def_options={}) @host, @options = host, def_options - @options_parser = StackTemplatePresetOptions.new(ARGV, def_options) + @options_parser = StackPresetOptions.new(ARGV, def_options) end def handle @@ -21,8 +20,8 @@ class StackTemplatePreset < Handler when :show show_handler output - when :build - build_handler + when :apply + apply_handler end end @@ -32,29 +31,29 @@ class StackTemplatePreset < Handler @options_parser.invalid_show_command abort(wrong_params) end - @show = get "/stack_template_presets/#{@args[2]}" + @show = get "/stack_presets/#{@args[2]}" end def list_handler - @list = get('/stack_template_presets') + @list = get('/stack_presets') end - def build_handler - wrong_params = inspect_parameters(@options_parser.build_params, @args[2]) + def apply_handler + wrong_params = inspect_parameters(@options_parser.apply_params, @args[2]) if wrong_params - @options_parser.invalid_build_command + @options_parser.invalid_apply_command abort(wrong_params) end params = {} params[:id] = @args[2] params[:provider] = options[:provider] || resources_selector.select_available_provider - params[:stack] = options[:stack] || enter_parameter(I18n.t('handler.stack_template_preset.create.stack')) + params[:stack] = options[:stack] || enter_parameter(I18n.t('handler.stack_preset.create.stack')) - filepath = options[:parameters_file] || enter_parameter(I18n.t('handler.stack_template_preset.create.parameters_file')) + filepath = options[:parameters_file] || enter_parameter(I18n.t('handler.stack_preset.create.parameters_file')) params[:parameters] = JSON.parse(File.read(filepath)) - result = post_body("/stack_template_presets/#{params[:id]}/build_stack_template", JSON.pretty_generate(params)) + result = post_body("/stack_presets/#{params[:id]}/apply", JSON.pretty_generate(params)) end end diff --git a/devops-client/lib/devops-client/options/stack_preset_options.rb b/devops-client/lib/devops-client/options/stack_preset_options.rb new file mode 100644 index 0000000..919e2dc --- /dev/null +++ b/devops-client/lib/devops-client/options/stack_preset_options.rb @@ -0,0 +1,33 @@ +require "devops-client/options/common_options" + +class StackPresetOptions < CommonOptions + + commands :list, :show, :apply + + def initialize args, def_options + super(args, def_options) + self.header = I18n.t("headers.stack_preset") + self.banner_header = "stack_preset" + self.list_params = ["[provider]", "[ec2|openstack]"] + self.show_params = ["STACK"] + self.apply_params = ["PRESET"] + end + + def apply_options + self.options do |parser, options| + parser.banner << self.apply_banner + + parser.recognize_option_value(:provider, 'stack_preset') + parser.recognize_option_value(:stack, 'stack_preset') + parser.recognize_option_value(:parameters_file, 'stack_preset') + end + end + + + extend_options_method :list_options do |options| + if args[2] + options[:given_provider] = args[2] + end + end + +end diff --git a/devops-client/lib/devops-client/options/stack_template_preset_options.rb b/devops-client/lib/devops-client/options/stack_template_preset_options.rb deleted file mode 100644 index 237503d..0000000 --- a/devops-client/lib/devops-client/options/stack_template_preset_options.rb +++ /dev/null @@ -1,33 +0,0 @@ -require "devops-client/options/common_options" - -class StackTemplatePresetOptions < CommonOptions - - commands :list, :show, :build - - def initialize args, def_options - super(args, def_options) - self.header = I18n.t("headers.stack_template_preset") - self.banner_header = "stack_template_preset" - self.list_params = ["[provider]", "[ec2|openstack]"] - self.show_params = ["STACK"] - self.build_params = ["PRESET"] - end - - def build_options - self.options do |parser, options| - parser.banner << self.build_banner - - parser.recognize_option_value(:provider, 'stack_template_preset') - parser.recognize_option_value(:stack, 'stack_template_preset') - parser.recognize_option_value(:parameters_file, 'stack_template_preset') - end - end - - - extend_options_method :list_options do |options| - if args[2] - options[:given_provider] = args[2] - end - end - -end diff --git a/devops-client/lib/devops-client/output/stack_template_preset.rb b/devops-client/lib/devops-client/output/stack_preset.rb similarity index 77% rename from devops-client/lib/devops-client/output/stack_template_preset.rb rename to devops-client/lib/devops-client/output/stack_preset.rb index 6e61349..184c944 100644 --- a/devops-client/lib/devops-client/output/stack_template_preset.rb +++ b/devops-client/lib/devops-client/output/stack_preset.rb @@ -1,11 +1,11 @@ require "devops-client/output/base" module Output - class StackTemplatePreset < Base + class StackPreset < Base def table if outputting_list? - title = I18n.t("output.title.stack_template_preset.list") + title = I18n.t("output.title.stack_preset.list") headers, rows = create_list create_table headers, rows, title, with_num? else @@ -29,7 +29,7 @@ module Output private def create_list - abort(I18n.t("output.not_found.stack_template_preset.list")) if @data.empty? + abort(I18n.t("output.not_found.stack_preset.list")) if @data.empty? fields_to_output = %w(id) diff --git a/devops-client/locales/en.yml b/devops-client/locales/en.yml index a13f9cb..1797aba 100644 --- a/devops-client/locales/en.yml +++ b/devops-client/locales/en.yml @@ -43,7 +43,7 @@ en: user: "User" stack: "Stack" stack_template: "Stack template" - stack_template_preset: "Stack template preset" + stack_preset: "Stack template preset" handler: flavor: list: @@ -118,10 +118,10 @@ en: question: create: "Are you sure to create stack?" delete: "Are you sure to delete stack '%{name}'?" - stack_template_preset: + stack_preset: create: parameters_file: 'Path to file with JSON parameters: ' - stack_template: 'Name of stack template to build: ' + stack: 'Name of stack to create: ' message: choose_list_default: "Choose %{name} (comma separated), like 1,2,3 or empty for default value '%{default}': " choose_list: "Choose %{name} (comma separated), like 1,2,3: " @@ -235,7 +235,7 @@ en: stack_template: list: "Stack Templates" show: "Stack Template" - stack_template_preset: + stack_preset: list: "Stack Template Presets" show: "Stack Template Preset" stack: @@ -272,7 +272,7 @@ en: stack_template: list: "No stack templates found" show: "There isn't such stack template" - stack_template_preset: + stack_preset: list: "No stack template presets found" show: "There isn't such stack template preset" stack: @@ -378,7 +378,7 @@ en: provider: Stack template provider id: Stack template id template_file: Stack template file - stack_template_preset: + stack_preset: parameters_file: Path to file with JSON parameters stack: 'Name of stack to build: ' provider: Stack provider diff --git a/devops-service/app/devops-api2.rb b/devops-service/app/devops-api2.rb index 7635d4c..88eb263 100644 --- a/devops-service/app/devops-api2.rb +++ b/devops-service/app/devops-api2.rb @@ -21,7 +21,7 @@ module Devops require "routes/v2.0/handlers/server" require "routes/v2.0/handlers/stack" require "routes/v2.0/handlers/stack_template" - require "routes/v2.0/stack_template_presets" + require "routes/v2.0/stack_presets" require "routes/v2.0/handlers/report" require 'lib/stubber' @@ -60,7 +60,7 @@ module Devops require "routes/v2.0/bootstrap_templates" require "routes/v2.0/stack" require "routes/v2.0/stack_template" - require "routes/v2.0/handlers/stack_template_preset" + require "routes/v2.0/handlers/stack_preset" require "routes/v2.0/report" routes = Devops::Version2_0::Routes.constants.collect{|s| Devops::Version2_0::Routes.const_get(s)}.select {|const| const.class == Module} diff --git a/devops-service/lib/stack_template_presets/base.rb b/devops-service/lib/stack_presets/base.rb similarity index 93% rename from devops-service/lib/stack_template_presets/base.rb rename to devops-service/lib/stack_presets/base.rb index 3914b62..d19ca77 100644 --- a/devops-service/lib/stack_template_presets/base.rb +++ b/devops-service/lib/stack_presets/base.rb @@ -2,7 +2,7 @@ require 'lib/string_helper' require 'db/mongo/models/stack_template/stack_template_factory' module Devops - module StackTemplatePresets + module StackPresets class Base def id @@ -25,7 +25,7 @@ module Devops end def template_body - @template_body ||= File.read("lib/stack_template_presets/#{id}.#{template_file_extension}") + @template_body ||= File.read("lib/stack_presets/#{id}.#{template_file_extension}") end # some templates may be YAML files diff --git a/devops-service/lib/stack_template_presets/factory.rb b/devops-service/lib/stack_presets/factory.rb similarity index 56% rename from devops-service/lib/stack_template_presets/factory.rb rename to devops-service/lib/stack_presets/factory.rb index f3cb3ad..1bb613e 100644 --- a/devops-service/lib/stack_template_presets/factory.rb +++ b/devops-service/lib/stack_presets/factory.rb @@ -2,15 +2,15 @@ require_relative 'base' require_relative 'postgres_cluster' require_relative 'preset_not_found' -class Devops::StackTemplatePresetsFactory +class Devops::StackPresetsFactory - # find all classes in Devops::StackTemplatePresets modules excluding Base and factory. - # This list can be extended in external gems via defining new classes in Devops::StackTemplatePresets module. + # find all classes in Devops::StackPresets modules excluding Base and factory. + # This list can be extended in external gems via defining new classes in Devops::StackPresets module. def self.list - @list ||= Devops::StackTemplatePresets.constants.select do |class_name| + @list ||= Devops::StackPresets.constants.select do |class_name| class_name != :Base end.map do |class_name| - Devops::StackTemplatePresets.const_get(class_name).new + Devops::StackPresets.const_get(class_name).new end end diff --git a/devops-service/lib/stack_template_presets/postgres_cluster.rb b/devops-service/lib/stack_presets/postgres_cluster.rb similarity index 71% rename from devops-service/lib/stack_template_presets/postgres_cluster.rb rename to devops-service/lib/stack_presets/postgres_cluster.rb index 9f55456..21f165a 100644 --- a/devops-service/lib/stack_template_presets/postgres_cluster.rb +++ b/devops-service/lib/stack_presets/postgres_cluster.rb @@ -1,4 +1,4 @@ -module Devops::StackTemplatePresets +module Devops::StackPresets class PostgresCluster < Base def template_file_extension :yml diff --git a/devops-service/lib/stack_template_presets/postgres_cluster.yml b/devops-service/lib/stack_presets/postgres_cluster.yml similarity index 100% rename from devops-service/lib/stack_template_presets/postgres_cluster.yml rename to devops-service/lib/stack_presets/postgres_cluster.yml diff --git a/devops-service/lib/stack_template_presets/preset_not_found.rb b/devops-service/lib/stack_presets/preset_not_found.rb similarity index 100% rename from devops-service/lib/stack_template_presets/preset_not_found.rb rename to devops-service/lib/stack_presets/preset_not_found.rb diff --git a/devops-service/routes/v2.0/handlers/stack_template_preset.rb b/devops-service/routes/v2.0/handlers/stack_preset.rb similarity index 56% rename from devops-service/routes/v2.0/handlers/stack_template_preset.rb rename to devops-service/routes/v2.0/handlers/stack_preset.rb index 1d71146..376606f 100644 --- a/devops-service/routes/v2.0/handlers/stack_template_preset.rb +++ b/devops-service/routes/v2.0/handlers/stack_preset.rb @@ -1,35 +1,35 @@ require 'json' -require 'lib/stack_template_presets/factory' +require 'lib/stack_presets/factory' module Devops module Version2_0 module Handler - class StackTemplatePreset + class StackPreset def self.get_presets lambda { - # check_privileges("stack_template_presets", "r") - json Devops::StackTemplatePresetsFactory.list.map(&:to_hash) + # check_privileges("stack_presets", "r") + json Devops::StackPresetsFactory.list.map(&:to_hash) } end def self.get_preset lambda { - # check_privileges("stack_template_presets", "r") - json Devops::StackTemplatePresetsFactory.get(params['id']).to_hash + # check_privileges("stack_presets", "r") + json Devops::StackPresetsFactory.get(params['id']).to_hash } end - def self.build_stack_template + def self.apply lambda { - # check_privileges("stack_template_presets", "r") + # check_privileges("stack_presets", "r") check_privileges('stack_template', 'w') attrs = create_object_from_json_body provider, stack_id, parameters = attrs.fetch('provider'), attrs.fetch('stack'), attrs.fetch('parameters') - preset = Devops::StackTemplatePresetsFactory.get(attrs.fetch('id')) + preset = Devops::StackPresetsFactory.get(attrs.fetch('id')) stack = preset.create_stack_from_preset(provider, stack_id, parameters) settings.mongo.stack_insert(stack) diff --git a/devops-service/routes/v2.0/stack_template_presets.rb b/devops-service/routes/v2.0/stack_presets.rb similarity index 65% rename from devops-service/routes/v2.0/stack_template_presets.rb rename to devops-service/routes/v2.0/stack_presets.rb index 8cdb70d..1e34816 100644 --- a/devops-service/routes/v2.0/stack_template_presets.rb +++ b/devops-service/routes/v2.0/stack_presets.rb @@ -1,10 +1,10 @@ module Devops module Version2_0 module Routes - module StackTemplatePresetRoutes + module StackPresetRoutes def self.registered(app) - # Get list of available stack_template_presets + # Get list of available stack_presets # # * *Request* # - method : GET @@ -14,10 +14,10 @@ module Devops # * *Returns* : array of hashes # [ {id: 'preset id', template_preset_body: 'long body'} ] # - app.get_with_headers "/stack_template_presets", :headers => [:accept], &Devops::Version2_0::Handler::StackTemplatePreset.get_presets + app.get_with_headers "/stack_presets", :headers => [:accept], &Devops::Version2_0::Handler::StackPreset.get_presets - # Get information about stack_template_preset + # Get information about stack_preset # # * *Request* # - method : GET @@ -27,7 +27,7 @@ module Devops # * *Returns* : hash # {id: 'preset id', template_preset_body: 'long body'} # - app.get_with_headers "/stack_template_presets/:id", :headers => [:accept], &Devops::Version2_0::Handler::StackTemplatePreset.get_preset + app.get_with_headers "/stack_presets/:id", :headers => [:accept], &Devops::Version2_0::Handler::StackPreset.get_preset # Build stack template from preset @@ -38,7 +38,7 @@ module Devops # - Accept: application/json # - params : # - provider: string - # - stack_template_id: id of stack template to create + # - stack_id: id of stack template to create # - template_attrs: hash with template attributes # # TODO: not stack template, but stack itself @@ -50,7 +50,7 @@ module Devops # template_body: 'long body' # } # - app.post_with_headers "/stack_template_presets/:id/build_stack_template", :headers => [:accept], &Devops::Version2_0::Handler::StackTemplatePreset.build_stack_template + app.post_with_headers "/stack_presets/:id/apply", :headers => [:accept], &Devops::Version2_0::Handler::StackPreset.apply puts "Stack template presets routes initialized" end diff --git a/devops-service/tests/generate_tests.rb b/devops-service/tests/generate_tests.rb index ded4523..e5a0f4d 100755 --- a/devops-service/tests/generate_tests.rb +++ b/devops-service/tests/generate_tests.rb @@ -77,7 +77,7 @@ templates = { #list "templates/api_v2/00_list/flavor.feature.erb" => "features/api_v2/00_list/flavor.feature", - "templates/api_v2/00_list/stack_template_preset.feature.erb" => "features/api_v2/00_list/stack_template_preset.feature", + "templates/api_v2/00_list/stack_preset.feature.erb" => "features/api_v2/00_list/stack_preset.feature", "templates/api_v2/00_list/10_user.feature.erb" => "features/api_v2/00_list/10_user.feature", #create diff --git a/devops-service/tests/stubs/providers/openstack.rb b/devops-service/tests/stubs/providers/openstack.rb index 0247888..8c3159f 100644 --- a/devops-service/tests/stubs/providers/openstack.rb +++ b/devops-service/tests/stubs/providers/openstack.rb @@ -71,4 +71,12 @@ class Provider::Openstack true end + def stack_details + {stack_status: 'stubbed'} + end + + def stack_resources + ['stubbed'] + end + end \ No newline at end of file diff --git a/devops-service/tests/templates/api_v2/00_list/stack_template_preset.feature.erb b/devops-service/tests/templates/api_v2/00_list/stack_template_preset.feature.erb index 52e63fb..77690e4 100644 --- a/devops-service/tests/templates/api_v2/00_list/stack_template_preset.feature.erb +++ b/devops-service/tests/templates/api_v2/00_list/stack_template_preset.feature.erb @@ -1,8 +1,8 @@ -@stack_template_preset +@stack_preset Feature: stack template preset list Scenario: Get list of all stack template presets - When I send GET '/v2.0/stack_template_presets' query + When I send GET '/v2.0/stack_presets' query Then response should be '200' And the Content-Type header should include 'application/json' And the JSON response should be an array @@ -17,7 +17,7 @@ Feature: stack template preset list """ Scenario: Get information about particular stack template preset - When I send GET '/v2.0/stack_template_presets/postgres_cluster' query + When I send GET '/v2.0/stack_presets/postgres_cluster' query Then response should be '200' And the Content-Type header should include 'application/json' And response should be JSON object like: From 58e0f4d118d7acf6a12a3689f6fcec5b5d74b5d2 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Thu, 16 Jul 2015 17:01:53 +0400 Subject: [PATCH 08/10] set project and deploy_env attrs to stack created from presets --- .../lib/devops-client/handler/stack.rb | 8 +++++-- .../lib/devops-client/handler/stack_preset.rb | 2 ++ devops-service/db/mongo/models/project.rb | 2 +- .../db/mongo/models/stack/stack_base.rb | 8 +++++-- devops-service/lib/stack_presets/base.rb | 21 ++++++++++++------- devops-service/providers/openstack.rb | 4 ++++ devops-service/routes/v2.0/handlers/stack.rb | 8 +++++++ .../routes/v2.0/handlers/stack_preset.rb | 5 +---- devops-service/routes/v2.0/stack.rb | 2 ++ .../tests/stubs/providers/openstack.rb | 10 ++++++--- 10 files changed, 51 insertions(+), 19 deletions(-) diff --git a/devops-client/lib/devops-client/handler/stack.rb b/devops-client/lib/devops-client/handler/stack.rb index 782f958..2625d3e 100644 --- a/devops-client/lib/devops-client/handler/stack.rb +++ b/devops-client/lib/devops-client/handler/stack.rb @@ -79,13 +79,17 @@ class Stack < Handler end def resources_handler - stack_id = @args[2] + stack_id, resource_id = @args[2], @args[3] r = inspect_parameters(@options_parser.sync_params, stack_id) unless r.nil? @options_parser.invalid_sync_command abort(r) end - @list = get "/stack/#{stack_id}/resources" + if resource_id + @list = get "/stack/#{stack_id}/resources/#{resource_id}" + else + @list = get "/stack/#{stack_id}/resources" + end end def delete_handler diff --git a/devops-client/lib/devops-client/handler/stack_preset.rb b/devops-client/lib/devops-client/handler/stack_preset.rb index 427cdfe..a6df6d9 100644 --- a/devops-client/lib/devops-client/handler/stack_preset.rb +++ b/devops-client/lib/devops-client/handler/stack_preset.rb @@ -49,6 +49,8 @@ class StackPreset < Handler params[:id] = @args[2] params[:provider] = options[:provider] || resources_selector.select_available_provider params[:stack] = options[:stack] || enter_parameter(I18n.t('handler.stack_preset.create.stack')) + params[:project] = options[:project] || resources_selector.select_available_project + params[:deploy_env] = options[:deploy_env] || enter_parameter(I18n.t('handler.stack.create.deploy_env')) filepath = options[:parameters_file] || enter_parameter(I18n.t('handler.stack_preset.create.parameters_file')) params[:parameters] = JSON.parse(File.read(filepath)) diff --git a/devops-service/db/mongo/models/project.rb b/devops-service/db/mongo/models/project.rb index 98a010a..20cc25b 100644 --- a/devops-service/db/mongo/models/project.rb +++ b/devops-service/db/mongo/models/project.rb @@ -136,7 +136,7 @@ module Devops def to_hash_without_id h = {} h["deploy_envs"] = self.deploy_envs.map {|e| e.to_hash} unless self.deploy_envs.nil? - h["archived"] = self.archived + h["archived"] = self.archived if self.archived h["description"] = self.description if self.multi? h["type"] = MULTI_TYPE diff --git a/devops-service/db/mongo/models/stack/stack_base.rb b/devops-service/db/mongo/models/stack/stack_base.rb index 1c4fd20..695331f 100644 --- a/devops-service/db/mongo/models/stack/stack_base.rb +++ b/devops-service/db/mongo/models/stack/stack_base.rb @@ -7,8 +7,8 @@ module Devops types id: {type: String, empty: false}, provider: {type: String, empty: false}, - project: {type: String, nil: true}, - deploy_env: {type: String, nil: true}, + project: {type: String}, + deploy_env: {type: String}, stack_template: {type: String, empty: false}, cloud_stack_id: {type: String, nil: true} # details: {type: String, nil: true} @@ -59,6 +59,10 @@ module Devops provider_class.stack_resources(self) end + def resource(resource_id) + provider_class.stack_resource(self, resource_id) + end + def template_body Devops::Api2.settings.mongo.stack_template(stack_template).template_body end diff --git a/devops-service/lib/stack_presets/base.rb b/devops-service/lib/stack_presets/base.rb index d19ca77..ae09ac7 100644 --- a/devops-service/lib/stack_presets/base.rb +++ b/devops-service/lib/stack_presets/base.rb @@ -13,15 +13,22 @@ module Devops {id: id, template_body: template_body} end - def create_stack_from_preset(provider, stack_id, parameters) + # attrs should include + # 'provider' + # 'stack' + # 'parameters' + # 'project' + # 'deploy_env' + def create_stack_from_preset(attrs) + provider = attrs.fetch('provider') template_name = find_or_create_stack_template!(provider) - puts "Using #{template_name} stack_template to create new stack" - Model::StackFactory.create(provider, { - 'id' => stack_id, - 'provider' => provider, - 'parameters' => parameters, + + stack_attrs = attrs.merge( + 'id' => attrs['stack'], 'stack_template' => template_name - }) + ) + + Model::StackFactory.create(provider, stack_attrs) end def template_body diff --git a/devops-service/providers/openstack.rb b/devops-service/providers/openstack.rb index a5f74fb..a927741 100644 --- a/devops-service/providers/openstack.rb +++ b/devops-service/providers/openstack.rb @@ -217,6 +217,10 @@ module Provider fog_stack(stack).resources end + def stack_resource(stack, resource_id) + fog_stack(stack).resources.get(resource_id) + end + private def convert_groups list res = {} diff --git a/devops-service/routes/v2.0/handlers/stack.rb b/devops-service/routes/v2.0/handlers/stack.rb index cc5b652..c8a9731 100644 --- a/devops-service/routes/v2.0/handlers/stack.rb +++ b/devops-service/routes/v2.0/handlers/stack.rb @@ -74,6 +74,14 @@ module Devops } end + def self.resource + lambda { + check_privileges("stack", "r") + stack = settings.mongo.stack(params[:stack_id]) + json stack.resource(params[:resource_id]) + } + end + end end end diff --git a/devops-service/routes/v2.0/handlers/stack_preset.rb b/devops-service/routes/v2.0/handlers/stack_preset.rb index 376606f..1b16e13 100644 --- a/devops-service/routes/v2.0/handlers/stack_preset.rb +++ b/devops-service/routes/v2.0/handlers/stack_preset.rb @@ -26,11 +26,8 @@ module Devops check_privileges('stack_template', 'w') attrs = create_object_from_json_body - - provider, stack_id, parameters = attrs.fetch('provider'), attrs.fetch('stack'), attrs.fetch('parameters') - preset = Devops::StackPresetsFactory.get(attrs.fetch('id')) - stack = preset.create_stack_from_preset(provider, stack_id, parameters) + stack = preset.create_stack_from_preset(attrs) settings.mongo.stack_insert(stack) create_response 'Created', stack.to_hash, 201 diff --git a/devops-service/routes/v2.0/stack.rb b/devops-service/routes/v2.0/stack.rb index 1d866aa..8634ae0 100644 --- a/devops-service/routes/v2.0/stack.rb +++ b/devops-service/routes/v2.0/stack.rb @@ -18,6 +18,8 @@ module Devops app.get_with_headers "/stack/:stack_id/resources", :headers => [:accept], &Devops::Version2_0::Handler::Stack.resources + app.get_with_headers "/stack/:stack_id/resources/:resource_id", :headers => [:accept], &Devops::Version2_0::Handler::Stack.resource + hash = {} hash['GET'] = Devops::Version2_0::Handler::Stack.get_stack diff --git a/devops-service/tests/stubs/providers/openstack.rb b/devops-service/tests/stubs/providers/openstack.rb index 8c3159f..d6b477d 100644 --- a/devops-service/tests/stubs/providers/openstack.rb +++ b/devops-service/tests/stubs/providers/openstack.rb @@ -71,12 +71,16 @@ class Provider::Openstack true end - def stack_details + def stack_details(stack) {stack_status: 'stubbed'} end - def stack_resources - ['stubbed'] + def stack_resources(stack) + [{'stubbed' => 'stubbed'}] + end + + def stack_resource(stack, resource_id) + {'stubbed' => 'stubbed'} end end \ No newline at end of file From 53a363682b125054dc1198febfa476817efd46fa Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Fri, 17 Jul 2015 13:01:13 +0300 Subject: [PATCH 09/10] rename test template --- ...stack_template_preset.feature.erb => stack_preset.feature.erb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename devops-service/tests/templates/api_v2/00_list/{stack_template_preset.feature.erb => stack_preset.feature.erb} (100%) diff --git a/devops-service/tests/templates/api_v2/00_list/stack_template_preset.feature.erb b/devops-service/tests/templates/api_v2/00_list/stack_preset.feature.erb similarity index 100% rename from devops-service/tests/templates/api_v2/00_list/stack_template_preset.feature.erb rename to devops-service/tests/templates/api_v2/00_list/stack_preset.feature.erb From 22430159147dcd80cb6570e4c4498014be611c3a Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Fri, 17 Jul 2015 15:15:52 +0300 Subject: [PATCH 10/10] add project and deploy_env params to stack template client handler --- devops-client/lib/devops-client/handler/stack_preset.rb | 3 ++- .../lib/devops-client/options/stack_preset_options.rb | 2 ++ devops-service/db/mongo/models/stack/stack_base.rb | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/devops-client/lib/devops-client/handler/stack_preset.rb b/devops-client/lib/devops-client/handler/stack_preset.rb index a6df6d9..b1e9073 100644 --- a/devops-client/lib/devops-client/handler/stack_preset.rb +++ b/devops-client/lib/devops-client/handler/stack_preset.rb @@ -22,6 +22,7 @@ class StackPreset < Handler output when :apply apply_handler + output end end @@ -55,7 +56,7 @@ class StackPreset < Handler filepath = options[:parameters_file] || enter_parameter(I18n.t('handler.stack_preset.create.parameters_file')) params[:parameters] = JSON.parse(File.read(filepath)) - result = post_body("/stack_presets/#{params[:id]}/apply", JSON.pretty_generate(params)) + @list = post_body("/stack_presets/#{params[:id]}/apply", JSON.pretty_generate(params)) end end diff --git a/devops-client/lib/devops-client/options/stack_preset_options.rb b/devops-client/lib/devops-client/options/stack_preset_options.rb index 919e2dc..0c8fde4 100644 --- a/devops-client/lib/devops-client/options/stack_preset_options.rb +++ b/devops-client/lib/devops-client/options/stack_preset_options.rb @@ -18,6 +18,8 @@ class StackPresetOptions < CommonOptions parser.banner << self.apply_banner parser.recognize_option_value(:provider, 'stack_preset') + parser.recognize_option_value(:project, 'stack_preset') + parser.recognize_option_value(:deploy_env, 'stack_preset') parser.recognize_option_value(:stack, 'stack_preset') parser.recognize_option_value(:parameters_file, 'stack_preset') end diff --git a/devops-service/db/mongo/models/stack/stack_base.rb b/devops-service/db/mongo/models/stack/stack_base.rb index 695331f..ac7410f 100644 --- a/devops-service/db/mongo/models/stack/stack_base.rb +++ b/devops-service/db/mongo/models/stack/stack_base.rb @@ -11,7 +11,7 @@ module Devops deploy_env: {type: String}, stack_template: {type: String, empty: false}, cloud_stack_id: {type: String, nil: true} - # details: {type: String, nil: true} + # details: {type: Hash, nil: true} # Hash type isn't supported yet def initialize attrs={} self.provider = self.class.provider