add sync method to stack

This commit is contained in:
Anton Chuchkalov 2015-07-14 17:51:40 +04:00
parent a72fc782a3
commit 7ac62a2a36
15 changed files with 99 additions and 57 deletions

View File

@ -13,7 +13,6 @@ class Stack < Handler
end end
def handle def handle
current_command = ARGV[1].to_sym
@options, @args = @options_parser.parse_options_for!(current_command) @options, @args = @options_parser.parse_options_for!(current_command)
case current_command case current_command
when :list when :list
@ -26,6 +25,9 @@ class Stack < Handler
create_handler create_handler
when :delete when :delete
delete_handler delete_handler
when :sync_details
sync_handler
output
end end
end end
@ -63,6 +65,16 @@ class Stack < Handler
@show = get "/stack/#{stack_id}" @show = get "/stack/#{stack_id}"
end 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 def delete_handler
stack_id = @args[2] stack_id = @args[2]
r = inspect_parameters(@options_parser.delete_params, stack_id) r = inspect_parameters(@options_parser.delete_params, stack_id)

View File

@ -2,7 +2,7 @@ require "devops-client/options/common_options"
class StackOptions < CommonOptions class StackOptions < CommonOptions
commands :create, :delete, :list, :show commands :create, :delete, :list, :show, :sync_details
def initialize args, def_options def initialize args, def_options
super(args, def_options) super(args, def_options)
@ -11,6 +11,7 @@ class StackOptions < CommonOptions
self.list_params = ["[provider]", "[ec2|openstack]"] self.list_params = ["[provider]", "[ec2|openstack]"]
self.show_params = ["STACK"] self.show_params = ["STACK"]
self.delete_params = ["STACK"] self.delete_params = ["STACK"]
self.sync_details_params = ["STACK"]
end end
def create_options def create_options

View File

@ -37,7 +37,7 @@ module Output
end end
def create_show 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
end end

View File

@ -196,6 +196,7 @@ en:
template_preset_body: "Template preset body" template_preset_body: "Template preset body"
stack_template: "Stack Template" stack_template: "Stack Template"
cloud_stack_id: "Cloud Stack id" cloud_stack_id: "Cloud Stack id"
details: "Details are not displayed in table view"
title: title:
flavor: flavor:
list: "Flavors" list: "Flavors"

View File

@ -4,9 +4,8 @@ module Connectors
module Helpers module Helpers
module UpdateCommand module UpdateCommand
# when included, this module adds method #update and alias for it. # this module adds methods #update and "#{resource_name}_update" (they are synonyms).
# Alias name depends on base class name. # We need second method name to forward methods from MongoConnector to resources connectors.
# We need this alias to forward methods from MongoConnector to resources connectors.
def self.included(base) def self.included(base)
resource_name = StringHelper.underscore_class(base) resource_name = StringHelper.underscore_class(base)

View File

@ -3,7 +3,8 @@ module Connectors
include Helpers::InsertCommand, include Helpers::InsertCommand,
Helpers::ShowCommand, Helpers::ShowCommand,
Helpers::ListCommand, Helpers::ListCommand,
Helpers::DeleteCommand Helpers::DeleteCommand,
Helpers::UpdateCommand
def initialize(db) def initialize(db)
self.collection = db.collection('stacks') self.collection = db.collection('stacks')

View File

@ -2,24 +2,27 @@ module Devops
module Model module Model
class StackBase < MongoModel 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}, types id: {type: String, empty: false},
provider: {type: String, empty: false}, provider: {type: String, empty: false},
project: {type: String, nil: true}, project: {type: String, nil: true},
deploy_env: {type: String, nil: true}, deploy_env: {type: String, nil: true},
stack_template: {type: String, empty: false} stack_template: {type: String, empty: false},
# cloud_stack_id: {type: String, empty: true} cloud_stack_id: {type: String, nil: true}
# TODO: add parameters Hash # details: {type: String, nil: true}
def initialize attrs={} def initialize attrs={}
self.provider = self.class.provider
self.id = attrs['id'] self.id = attrs['id']
self.provider = attrs['provider']
self.project = attrs['project'] self.project = attrs['project']
self.deploy_env = attrs['deploy_env'] self.deploy_env = attrs['deploy_env']
self.stack_template = attrs['stack_template'] 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.parameters = attrs['parameters']
self.details = attrs['details']
self self
end end
@ -30,39 +33,57 @@ module Devops
deploy_env: deploy_env, deploy_env: deploy_env,
stack_template: stack_template, stack_template: stack_template,
cloud_stack_id: cloud_stack_id, cloud_stack_id: cloud_stack_id,
parameters: parameters parameters: parameters,
details: details
} }
end 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! 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 end
def delete_stack_in_cloud! 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 end
def template_body def template_body
Devops::Api2.settings.mongo.stack_template(stack_template).template_body Devops::Api2.settings.mongo.stack_template(stack_template).template_body
end 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 end
end end

View File

@ -1,12 +1,7 @@
module Devops module Devops
module Model module Model
class StackEc2 < StackBase class StackEc2 < StackBase
self.provider = 'ec2'
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
end end
end end
end end

View File

@ -1,21 +1,7 @@
module Devops module Devops
module Model module Model
class StackOpenstack < StackBase class StackOpenstack < StackBase
self.provider = 'openstack'
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
end end
end end
end end

View File

@ -13,7 +13,7 @@ class MongoConnector
delegate( delegate(
[:images, :image, :image_insert, :image_delete, :image_update] => :images_connector, [: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_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, [:available_images, :add_available_images, :delete_available_images] => :filters_connector,
[:project, :projects_all, :projects, :project_names_with_envs, [:project, :projects_all, :projects, :project_names_with_envs,
:projects_by_image, :projects_by_user, :project_insert, :project_update, :projects_by_image, :projects_by_user, :project_insert, :project_update,

View File

@ -210,6 +210,10 @@ module Provider
orchestration.delete_stack(stack.id, stack.cloud_stack_id) orchestration.delete_stack(stack.id, stack.cloud_stack_id)
end end
def stack_details(stack)
orchestration.show_stack_details(stack.id, stack.cloud_stack_id).data
end
private private
def convert_groups list def convert_groups list
res = {} res = {}

View File

@ -54,6 +54,18 @@ module Devops
} }
end 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 end
end end

View File

@ -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", :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 = {}
hash['GET'] = Devops::Version2_0::Handler::Stack.get_stack hash['GET'] = Devops::Version2_0::Handler::Stack.get_stack

View File

@ -62,4 +62,12 @@ class Provider::Ec2
] ]
end 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 end

View File

@ -11,7 +11,7 @@ Feature: stack template preset list
[ [
{ {
"id": "test", "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: And response should be JSON object like:
""" """
{ {
"id": "postgres_cluster", "template_preset_body": "long body" "id": "postgres_cluster", "template_body": "long body"
} }
""" """