Merge remote-tracking branch 'origin/devops_3_achuchkalov' into devops_3_amartynov
This commit is contained in:
commit
44e8a4be90
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
@ -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,12 @@ class Stack < Handler
|
||||
create_handler
|
||||
when :delete
|
||||
delete_handler
|
||||
when :sync
|
||||
sync_handler
|
||||
output
|
||||
when :resources
|
||||
resources_handler
|
||||
output('json')
|
||||
end
|
||||
end
|
||||
|
||||
@ -63,6 +68,30 @@ class Stack < Handler
|
||||
@show = get "/stack/#{stack_id}"
|
||||
end
|
||||
|
||||
def sync_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
|
||||
@show = post "/stack/#{stack_id}/sync_details"
|
||||
end
|
||||
|
||||
def resources_handler
|
||||
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
|
||||
if resource_id
|
||||
@list = get "/stack/#{stack_id}/resources/#{resource_id}"
|
||||
else
|
||||
@list = get "/stack/#{stack_id}/resources"
|
||||
end
|
||||
end
|
||||
|
||||
def delete_handler
|
||||
stack_id = @args[2]
|
||||
r = inspect_parameters(@options_parser.delete_params, stack_id)
|
||||
|
||||
@ -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,9 @@ class StackTemplatePreset < Handler
|
||||
when :show
|
||||
show_handler
|
||||
output
|
||||
when :build
|
||||
build_handler
|
||||
when :apply
|
||||
apply_handler
|
||||
output
|
||||
end
|
||||
end
|
||||
|
||||
@ -32,29 +32,31 @@ 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'))
|
||||
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_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))
|
||||
@list = post_body("/stack_presets/#{params[:id]}/apply", JSON.pretty_generate(params))
|
||||
end
|
||||
|
||||
end
|
||||
@ -2,7 +2,7 @@ require "devops-client/options/common_options"
|
||||
|
||||
class StackOptions < CommonOptions
|
||||
|
||||
commands :create, :delete, :list, :show
|
||||
commands :create, :delete, :list, :show, :sync, :resources
|
||||
|
||||
def initialize args, def_options
|
||||
super(args, def_options)
|
||||
@ -11,6 +11,8 @@ class StackOptions < CommonOptions
|
||||
self.list_params = ["[provider]", "[ec2|openstack]"]
|
||||
self.show_params = ["STACK"]
|
||||
self.delete_params = ["STACK"]
|
||||
self.sync_params = ["STACK"]
|
||||
self.resources_params = ["STACK"]
|
||||
end
|
||||
|
||||
def create_options
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
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(: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
|
||||
end
|
||||
|
||||
|
||||
extend_options_method :list_options do |options|
|
||||
if args[2]
|
||||
options[:given_provider] = args[2]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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))
|
||||
headers_and_rows([@data], %w(id deploy_env stack_template cloud_stack_id stack_status))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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: "
|
||||
@ -196,6 +196,7 @@ en:
|
||||
template_preset_body: "Template preset body"
|
||||
stack_template: "Stack Template"
|
||||
cloud_stack_id: "Cloud Stack id"
|
||||
stack_status: Stack status
|
||||
title:
|
||||
flavor:
|
||||
list: "Flavors"
|
||||
@ -234,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:
|
||||
@ -271,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:
|
||||
@ -377,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
|
||||
|
||||
@ -10,8 +10,8 @@ module Devops
|
||||
Devops::Db.connector.stacks
|
||||
end
|
||||
|
||||
def stacks_for_provider
|
||||
Devops::Db.connector.stacks(@params[:provider])
|
||||
def stacks_for_provider provider
|
||||
Devops::Db.connector.stacks(provider)
|
||||
end
|
||||
|
||||
def create_stack object
|
||||
@ -30,6 +30,21 @@ module Devops
|
||||
Devops::Db.connector.stack_delete(id)
|
||||
end
|
||||
|
||||
def sync_details id
|
||||
stack = self.stack(id)
|
||||
stack.sync_details!
|
||||
Devops::Db.connector.stack_update(stack)
|
||||
end
|
||||
|
||||
def resources id
|
||||
stack = Devops::Db.connector.stack(id)
|
||||
stack.resources
|
||||
end
|
||||
|
||||
def resources id, resource_id
|
||||
stack = Devops::Db.connector.stack(id)
|
||||
stack.resource(resource_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
28
devops-service/app/api2/handlers/stack_preset.rb
Normal file
28
devops-service/app/api2/handlers/stack_preset.rb
Normal file
@ -0,0 +1,28 @@
|
||||
require 'json'
|
||||
require 'lib/stack_presets/factory'
|
||||
require_relative "request_handler"
|
||||
|
||||
module Devops
|
||||
module API2_0
|
||||
module Handler
|
||||
class StackPreset < RequestHandler
|
||||
|
||||
def presets
|
||||
Devops::StackPresetsFactory.list
|
||||
end
|
||||
|
||||
def preset id
|
||||
Devops::StackPresetsFactory.get(id)
|
||||
end
|
||||
|
||||
def apply id, body
|
||||
preset = Devops::StackPresetsFactory.get(id)
|
||||
preset.create_stack_from_preset(body)
|
||||
Devops::Db.connector.stack_insert(stack)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
require 'json'
|
||||
require 'lib/stack_template_presets/factory'
|
||||
require_relative "request_handler"
|
||||
|
||||
module Devops
|
||||
module API2_0
|
||||
module Handler
|
||||
class StackTemplatePreset < RequestHandler
|
||||
|
||||
def templates
|
||||
Devops::StackTemplatePresetsFactory.list
|
||||
end
|
||||
|
||||
def template id
|
||||
Devops::StackTemplatePresetsFactory.get(id)
|
||||
end
|
||||
|
||||
def build_stack_template id, body
|
||||
provider, stack_id, parameters = body.fetch('provider'), body.fetch('stack'), body.fetch('parameters')
|
||||
|
||||
preset = Devops::StackTemplatePresetsFactory.get(id)
|
||||
preset.create_stack_from_preset(provider, stack_id, parameters)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -13,7 +13,7 @@ module Devops
|
||||
app.get_with_headers '/stacks/provider/:provider', :headers => [:accept] do |provider|
|
||||
check_privileges("stack", "r")
|
||||
check_provider(provider)
|
||||
json Devops::API2_0::Handler::Stack.new(request, params).stacks_for_provider.map(&:to_hash)
|
||||
json Devops::API2_0::Handler::Stack.new(request, params).stacks_for_provider(provider).map(&:to_hash)
|
||||
end
|
||||
|
||||
app.post_with_headers "/stack", :headers => [:accept] do
|
||||
@ -35,9 +35,23 @@ module Devops
|
||||
Devops::API2_0::Handler::Stack.new(request, params).delete_stack(stack_id)
|
||||
create_response("Stack '#{stack_id}' has been removed")
|
||||
}
|
||||
|
||||
app.multi_routes '/stack/:stack_id', {:headers => [:accept]}, hash
|
||||
|
||||
app.post_with_headers "/stack/:stack_id/sync_details", :headers => [:accept] do |stack_id|
|
||||
check_privileges("stack", "w")
|
||||
json Devops::API2_0::Handler::Stack.new(request, params).sync_details(stack_id).to_hash
|
||||
end
|
||||
|
||||
app.get_with_headers "/stack/:stack_id/resources", :headers => [:accept] do |stack_id|
|
||||
check_privileges("stack", "r")
|
||||
json Devops::API2_0::Handler::Stack.new(request, params).resources(stack_id)
|
||||
end
|
||||
|
||||
app.get_with_headers "/stack/:stack_id/resources/:resource_id", :headers => [:accept] do |stack_id, resource_id|
|
||||
check_privileges("stack", "r")
|
||||
json Devops::API2_0::Handler::Stack.new(request, params).resource(stack_id, resource_id)
|
||||
end
|
||||
|
||||
puts "Stack routes initialized"
|
||||
end
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
module Devops
|
||||
module API2_0
|
||||
module Routes
|
||||
module StackTemplatePresetRoutes
|
||||
module StackPresetRoutes
|
||||
|
||||
def self.registered(app)
|
||||
# Get list of available stack_template_presets
|
||||
@ -14,9 +14,9 @@ module Devops
|
||||
# * *Returns* : array of hashes
|
||||
# [ {id: 'preset id', template_preset_body: 'long body'} ]
|
||||
#
|
||||
app.get_with_headers "/stack_template_presets", :headers => [:accept] do
|
||||
app.get_with_headers "/stack_presets", :headers => [:accept] do
|
||||
# check_privileges("stack_template_presets", "r")
|
||||
json Devops::API2_0::Handler::StackTemplatePreset.new(request, params).templates.map(&:to_hash)
|
||||
json Devops::API2_0::Handler::StackPreset.new(request, params).presets.map(&:to_hash)
|
||||
end
|
||||
|
||||
# Get information about stack_template_preset
|
||||
@ -29,9 +29,9 @@ module Devops
|
||||
# * *Returns* : hash
|
||||
# {id: 'preset id', template_preset_body: 'long body'}
|
||||
#
|
||||
app.get_with_headers "/stack_template_presets/:id", :headers => [:accept] do |id|
|
||||
app.get_with_headers "/stack_presets/:id", :headers => [:accept] do |id|
|
||||
# check_privileges("stack_template_presets", "r")
|
||||
json Devops::API2_0::Handler::StackTemplatePreset.new(request, params).template(id).to_hash
|
||||
json Devops::API2_0::Handler::StackPreset.new(request, params).preset(id).to_hash
|
||||
end
|
||||
|
||||
# Build stack template from preset
|
||||
@ -54,11 +54,11 @@ module Devops
|
||||
# template_body: 'long body'
|
||||
# }
|
||||
#
|
||||
app.post_with_headers "/stack_template_presets/:id/build_stack_template", :headers => [:accept] do |id|
|
||||
app.post_with_headers "/stack_presets/:id/apply", :headers => [:accept] do |id|
|
||||
# check_privileges("stack_template_presets", "r")
|
||||
check_privileges('stack_template', 'w')
|
||||
body = create_object_from_json_body
|
||||
stack = Devops::API2_0::Handler::StackTemplatePreset.new(request, params).build_stack_template(id, body)
|
||||
stack = Devops::API2_0::Handler::StackPreset.new(request, params).apply(id, body)
|
||||
create_response 'Created', stack.to_hash, 201
|
||||
end
|
||||
|
||||
@ -21,7 +21,7 @@ module Devops
|
||||
|
||||
require_relative "api2/handlers/stack"
|
||||
require_relative "api2/handlers/stack_template"
|
||||
require_relative "api2/handlers/stack_template_preset"
|
||||
require_relative "api2/handlers/stack_preset"
|
||||
|
||||
require 'lib/stubber'
|
||||
end
|
||||
@ -58,6 +58,7 @@ module Devops
|
||||
require_relative "api2/routes/bootstrap_templates"
|
||||
require_relative "api2/routes/stack"
|
||||
require_relative "api2/routes/stack_template"
|
||||
require_relative "api2/routes/stack_preset"
|
||||
require_relative "api2/routes/report"
|
||||
|
||||
routes = Devops::API2_0::Routes.constants.collect{|s| Devops::API2_0::Routes.const_get(s)}.select {|const| const.class == Module}
|
||||
|
||||
@ -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
|
||||
|
||||
# set it to :all or [:ec2] to stub calls to selected providers
|
||||
# or to false to disable stubbing
|
||||
config[:stub_providers] = false
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -135,7 +135,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
|
||||
|
||||
@ -2,26 +2,27 @@ 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, :details
|
||||
|
||||
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}
|
||||
# cloud_stack_id: {type: String, empty: true}
|
||||
# TODO: add parameters Hash
|
||||
project: {type: String},
|
||||
deploy_env: {type: String},
|
||||
stack_template: {type: String, empty: false},
|
||||
cloud_stack_id: {type: String, nil: true}
|
||||
# details: {type: Hash, nil: true} # Hash type isn't supported yet
|
||||
|
||||
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.template_body = attrs['template_body']
|
||||
# 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
|
||||
|
||||
@ -32,40 +33,63 @@ module Devops
|
||||
deploy_env: deploy_env,
|
||||
stack_template: stack_template,
|
||||
cloud_stack_id: cloud_stack_id,
|
||||
parameters: parameters
|
||||
parameters: parameters,
|
||||
details: details,
|
||||
stack_status: stack_status
|
||||
}
|
||||
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!
|
||||
self.details = provider_class.stack_details(self)
|
||||
end
|
||||
|
||||
def resources
|
||||
provider_class.stack_resources(self)
|
||||
end
|
||||
|
||||
def resource(resource_id)
|
||||
provider_class.stack_resource(self, resource_id)
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,21 +1,11 @@
|
||||
module Devops
|
||||
module Model
|
||||
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
|
||||
def stack_status
|
||||
details[:stack_status] if details
|
||||
end
|
||||
|
||||
def delete_stack_in_cloud!
|
||||
provider = Provider::ProviderFactory.get('openstack')
|
||||
provider.delete_stack(self)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -12,8 +12,8 @@ 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,
|
||||
[: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,
|
||||
:projects_by_image, :projects_by_user, :project_insert, :project_update,
|
||||
|
||||
76
devops-service/lib/stack_presets/base.rb
Normal file
76
devops-service/lib/stack_presets/base.rb
Normal file
@ -0,0 +1,76 @@
|
||||
require 'lib/string_helper'
|
||||
require 'db/mongo/models/stack_template/stack_template_factory'
|
||||
|
||||
module Devops
|
||||
module StackPresets
|
||||
class Base
|
||||
|
||||
def id
|
||||
StringHelper.underscore_class(self.class)
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{id: id, template_body: template_body}
|
||||
end
|
||||
|
||||
# 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)
|
||||
|
||||
stack_attrs = attrs.merge(
|
||||
'id' => attrs['stack'],
|
||||
'stack_template' => template_name
|
||||
)
|
||||
|
||||
Model::StackFactory.create(provider, stack_attrs)
|
||||
end
|
||||
|
||||
def template_body
|
||||
@template_body ||= File.read("lib/stack_presets/#{id}.#{template_file_extension}")
|
||||
end
|
||||
|
||||
# some templates may be YAML files
|
||||
def template_file_extension
|
||||
:json
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_or_create_stack_template!(provider)
|
||||
name = stack_template_name(provider)
|
||||
begin
|
||||
stack_template = Devops::Api2.settings.mongo.stack_template(name)
|
||||
update_stack_template(stack_template) if stack_template.template_body != template_body
|
||||
rescue RecordNotFound
|
||||
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
|
||||
@ -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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module Devops::StackTemplatePresets
|
||||
module Devops::StackPresets
|
||||
class PostgresCluster < Base
|
||||
def template_file_extension
|
||||
:yml
|
||||
@ -13,5 +13,7 @@ resources:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
key_name: { get_param: key_name }
|
||||
image: 227f4be7-be1c-498d-ab88-54f8b5df249f
|
||||
flavor: m1.small
|
||||
image: 5f4020a1-b6ab-47e4-a0ed-de4324a17c3a
|
||||
flavor: m1.micro
|
||||
networks:
|
||||
- network: devops-net-1
|
||||
@ -1,38 +0,0 @@
|
||||
require 'lib/string_helper'
|
||||
require 'db/mongo/models/stack_template/stack_template_factory'
|
||||
|
||||
module Devops
|
||||
module StackTemplatePresets
|
||||
class Base
|
||||
|
||||
def id
|
||||
StringHelper.underscore_class(self.class)
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{id: id, template_preset_body: template_preset_body}
|
||||
end
|
||||
|
||||
def create_stack_from_preset(provider, stack_id, parameters)
|
||||
stack_attrs = {
|
||||
'id' => stack_id,
|
||||
'provider' => provider,
|
||||
'parameters' => parameters,
|
||||
'template_body' => template_preset_body
|
||||
}
|
||||
Model::StackFactory.create(provider, stack_attrs)
|
||||
end
|
||||
|
||||
def template_preset_body
|
||||
file_name = File.join("lib/stack_template_presets/#{id}.#{template_file_extension}")
|
||||
File.read(file_name)
|
||||
end
|
||||
|
||||
# some templates may be YAML files
|
||||
def template_file_extension
|
||||
:json
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -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
|
||||
|
||||
@ -193,11 +193,12 @@ 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
|
||||
})
|
||||
)
|
||||
response[:body]['stack']['id']
|
||||
rescue Excon::Errors::Conflict => e
|
||||
raise ProviderErrors::NameConflict
|
||||
@ -205,7 +206,19 @@ 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)
|
||||
fog_stack(stack).details.attributes
|
||||
end
|
||||
|
||||
def stack_resources(stack)
|
||||
fog_stack(stack).resources
|
||||
end
|
||||
|
||||
def stack_resource(stack, resource_id)
|
||||
fog_stack(stack).resources.get(resource_id)
|
||||
end
|
||||
|
||||
private
|
||||
@ -233,5 +246,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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -71,4 +71,16 @@ class Provider::Openstack
|
||||
true
|
||||
end
|
||||
|
||||
def stack_details(stack)
|
||||
{stack_status: 'stubbed'}
|
||||
end
|
||||
|
||||
def stack_resources(stack)
|
||||
[{'stubbed' => 'stubbed'}]
|
||||
end
|
||||
|
||||
def stack_resource(stack, resource_id)
|
||||
{'stubbed' => 'stubbed'}
|
||||
end
|
||||
|
||||
end
|
||||
@ -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
|
||||
@ -11,18 +11,18 @@ Feature: stack template preset list
|
||||
[
|
||||
{
|
||||
"id": "test",
|
||||
"template_preset_body": "long body"
|
||||
"template_body": "long body"
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
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:
|
||||
"""
|
||||
{
|
||||
"id": "postgres_cluster", "template_preset_body": "long body"
|
||||
"id": "postgres_cluster", "template_body": "long body"
|
||||
}
|
||||
"""
|
||||
Loading…
Reference in New Issue
Block a user