Merge branch 'devops_3_achuchkalov' of git.stu.neva.ru:cloudtechlab/devops-service into devops_3_achuchkalov

This commit is contained in:
Anton Chuchkalov 2015-07-17 12:25:11 +03:00
commit fa4b1089b6
39 changed files with 405 additions and 242 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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,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))
result = post_body("/stack_presets/#{params[:id]}/apply", JSON.pretty_generate(params))
end
end

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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'
@ -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
@ -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}

View File

@ -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

View File

@ -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)

View File

@ -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')

View File

@ -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')

View File

@ -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

View File

@ -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: 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.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
def create_stack_in_cloud!
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!
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
def template_body
Devops::Api2.settings.mongo.stack_template(stack_template).template_body
end
class << self
attr_accessor :provider
# attrs should include:
# - id (String)
# - provider (String)
# - deploy_env (String)
# - stack_template (String)
def self.create(attrs)
def create(attrs)
model = new(attrs)
model.create_stack_in_cloud!
model
end
def self.build_from_bson(attrs)
def build_from_bson(attrs)
attrs['id'] = attrs["_id"]
self.new(attrs)
end
def create_stack_in_cloud!
raise 'override me'
end
def delete_stack_in_cloud!
raise 'override me'
end
private
# 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
def provider_class
Provider::ProviderFactory.get(provider)
end
end

View File

@ -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

View File

@ -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"
def stack_status
details[:stack_status] if details
end
end
def delete_stack_in_cloud!
provider = Provider::ProviderFactory.get('openstack')
provider.delete_stack(self)
end
end
end
end

View File

@ -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,

View 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

View File

@ -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

View File

@ -1,4 +1,4 @@
module Devops::StackTemplatePresets
module Devops::StackPresets
class PostgresCluster < Base
def template_file_extension
:yml

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -54,6 +54,34 @@ 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
def self.resources
lambda {
check_privileges("stack", "r")
stack = settings.mongo.stack(params[:stack_id])
json stack.resources
}
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

View File

@ -0,0 +1,41 @@
require 'json'
require 'lib/stack_presets/factory'
module Devops
module Version2_0
module Handler
class StackPreset
def self.get_presets
lambda {
# check_privileges("stack_presets", "r")
json Devops::StackPresetsFactory.list.map(&:to_hash)
}
end
def self.get_preset
lambda {
# check_privileges("stack_presets", "r")
json Devops::StackPresetsFactory.get(params['id']).to_hash
}
end
def self.apply
lambda {
# check_privileges("stack_presets", "r")
check_privileges('stack_template', 'w')
attrs = create_object_from_json_body
preset = Devops::StackPresetsFactory.get(attrs.fetch('id'))
stack = preset.create_stack_from_preset(attrs)
settings.mongo.stack_insert(stack)
create_response 'Created', stack.to_hash, 201
}
end
end
end
end
end

View File

@ -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

View File

@ -1,43 +0,0 @@
require 'json'
require 'lib/stack_template_presets/factory'
module Devops
module Version2_0
module Handler
class StackTemplatePreset
def self.get_presets
lambda {
# check_privileges("stack_template_presets", "r")
json Devops::StackTemplatePresetsFactory.list.map(&:to_hash)
}
end
def self.get_preset
lambda {
# check_privileges("stack_template_presets", "r")
json Devops::StackTemplatePresetsFactory.get(params['id']).to_hash
}
end
def self.build_stack_template
lambda {
# check_privileges("stack_template_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'))
stack = preset.create_stack_from_preset(provider, stack_id, parameters)
create_response 'Created', stack.to_hash, 201
}
end
end
end
end
end

View File

@ -14,6 +14,12 @@ 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
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"
}
"""