Merge branch 'remove_stack_presets' into specs
This commit is contained in:
commit
b680b5cfa5
@ -47,9 +47,6 @@ class HandlerFactory
|
|||||||
when "stack_template"
|
when "stack_template"
|
||||||
require "devops-client/handler/stack_template"
|
require "devops-client/handler/stack_template"
|
||||||
StackTemplate
|
StackTemplate
|
||||||
when "stack_preset"
|
|
||||||
require "devops-client/handler/stack_preset"
|
|
||||||
StackPreset
|
|
||||||
when "stack"
|
when "stack"
|
||||||
require "devops-client/handler/stack"
|
require "devops-client/handler/stack"
|
||||||
Stack
|
Stack
|
||||||
|
|||||||
@ -15,7 +15,6 @@ class Image < 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
|
||||||
|
|||||||
@ -1,62 +0,0 @@
|
|||||||
require "devops-client/handler/handler"
|
|
||||||
require "devops-client/options/stack_preset_options"
|
|
||||||
require "devops-client/output/stack_preset"
|
|
||||||
|
|
||||||
class StackPreset < Handler
|
|
||||||
|
|
||||||
output_with Output::StackPreset
|
|
||||||
|
|
||||||
def initialize(host, def_options={})
|
|
||||||
@host, @options = host, def_options
|
|
||||||
@options_parser = StackPresetOptions.new(ARGV, def_options)
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle
|
|
||||||
@options, @args = @options_parser.parse_options_for!(current_command)
|
|
||||||
case current_command
|
|
||||||
when :list
|
|
||||||
list_handler
|
|
||||||
output
|
|
||||||
when :show
|
|
||||||
show_handler
|
|
||||||
output
|
|
||||||
when :apply
|
|
||||||
apply_handler
|
|
||||||
output
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def show_handler
|
|
||||||
wrong_params = inspect_parameters(@options_parser.show_params, @args[2])
|
|
||||||
if wrong_params
|
|
||||||
@options_parser.invalid_show_command
|
|
||||||
abort(wrong_params)
|
|
||||||
end
|
|
||||||
@show = get "/stack_presets/#{@args[2]}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_handler
|
|
||||||
@list = get('/stack_presets')
|
|
||||||
end
|
|
||||||
|
|
||||||
def apply_handler
|
|
||||||
wrong_params = inspect_parameters(@options_parser.apply_params, @args[2])
|
|
||||||
if wrong_params
|
|
||||||
@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_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))
|
|
||||||
|
|
||||||
@list = post_body("/stack_presets/#{params[:id]}/apply", JSON.pretty_generate(params))
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
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(:project, 'stack_preset')
|
|
||||||
parser.recognize_option_value(:deploy_env, '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,45 +0,0 @@
|
|||||||
require "devops-client/output/base"
|
|
||||||
|
|
||||||
module Output
|
|
||||||
class StackPreset < Base
|
|
||||||
|
|
||||||
def table
|
|
||||||
if outputting_list?
|
|
||||||
title = I18n.t("output.title.stack_preset.list")
|
|
||||||
headers, rows = create_list
|
|
||||||
else
|
|
||||||
title = I18n.t("output.title.stack.show", id: @data["id"])
|
|
||||||
headers, rows = create_apply
|
|
||||||
end
|
|
||||||
create_table headers, rows, title, with_num?
|
|
||||||
end
|
|
||||||
|
|
||||||
def csv
|
|
||||||
if outputting_list?
|
|
||||||
headers, rows = create_list
|
|
||||||
else
|
|
||||||
headers, rows = create_show
|
|
||||||
end
|
|
||||||
create_csv headers, rows, with_num?
|
|
||||||
end
|
|
||||||
|
|
||||||
def json
|
|
||||||
JSON.pretty_generate(@data)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def create_list
|
|
||||||
abort(I18n.t("output.not_found.stack_preset.list")) if @data.empty?
|
|
||||||
|
|
||||||
fields_to_output = %w(id)
|
|
||||||
|
|
||||||
headers_and_rows(@data, fields_to_output)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_apply
|
|
||||||
headers_and_rows([@data], %w(id deploy_env stack_template cloud_stack_id stack_status))
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -43,7 +43,6 @@ en:
|
|||||||
user: "User"
|
user: "User"
|
||||||
stack: "Stack"
|
stack: "Stack"
|
||||||
stack_template: "Stack template"
|
stack_template: "Stack template"
|
||||||
stack_preset: "Stack template preset"
|
|
||||||
handler:
|
handler:
|
||||||
flavor:
|
flavor:
|
||||||
list:
|
list:
|
||||||
@ -119,10 +118,6 @@ en:
|
|||||||
question:
|
question:
|
||||||
create: "Are you sure to create stack?"
|
create: "Are you sure to create stack?"
|
||||||
delete: "Are you sure to delete stack '%{name}'?"
|
delete: "Are you sure to delete stack '%{name}'?"
|
||||||
stack_preset:
|
|
||||||
create:
|
|
||||||
parameters_file: "Path to file with JSON parameters: "
|
|
||||||
stack: 'Name of stack to create: '
|
|
||||||
message:
|
message:
|
||||||
choose_list_default: "Choose %{name} (comma separated), like 1,2,3 or empty for default value '%{default}': "
|
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: "
|
choose_list: "Choose %{name} (comma separated), like 1,2,3: "
|
||||||
@ -236,9 +231,6 @@ en:
|
|||||||
stack_template:
|
stack_template:
|
||||||
list: "Stack Templates"
|
list: "Stack Templates"
|
||||||
show: "Stack Template"
|
show: "Stack Template"
|
||||||
stack_preset:
|
|
||||||
list: "Stack Template Presets"
|
|
||||||
show: "Stack Template Preset"
|
|
||||||
stack:
|
stack:
|
||||||
list: "Stacks"
|
list: "Stacks"
|
||||||
show: "Stack"
|
show: "Stack"
|
||||||
@ -274,9 +266,6 @@ en:
|
|||||||
stack_template:
|
stack_template:
|
||||||
list: "No stack templates found"
|
list: "No stack templates found"
|
||||||
show: "There isn't such stack template"
|
show: "There isn't such stack template"
|
||||||
stack_preset:
|
|
||||||
list: "No stack template presets found"
|
|
||||||
show: "There isn't such stack template preset"
|
|
||||||
stack:
|
stack:
|
||||||
list: "No stacks found"
|
list: "No stacks found"
|
||||||
show: "There isn't such stack"
|
show: "There isn't such stack"
|
||||||
@ -382,9 +371,5 @@ en:
|
|||||||
provider: Stack template provider
|
provider: Stack template provider
|
||||||
id: Stack template id
|
id: Stack template id
|
||||||
template_file: Stack template file
|
template_file: Stack template file
|
||||||
stack_preset:
|
|
||||||
parameters_file: Path to file with JSON parameters
|
|
||||||
stack: 'Name of stack to build: '
|
|
||||||
provider: Stack provider
|
|
||||||
user:
|
user:
|
||||||
new_password: New user password
|
new_password: New user password
|
||||||
|
|||||||
@ -1,43 +0,0 @@
|
|||||||
require 'json'
|
|
||||||
require 'lib/stack_presets/factory'
|
|
||||||
require 'workers/stack_bootstrap_worker'
|
|
||||||
require "app/api2/parsers/stack_preset"
|
|
||||||
require_relative "request_handler"
|
|
||||||
|
|
||||||
module Devops
|
|
||||||
module API2_0
|
|
||||||
module Handler
|
|
||||||
class StackPreset < RequestHandler
|
|
||||||
|
|
||||||
set_parser Devops::API2_0::Parser::StackPresetParser
|
|
||||||
|
|
||||||
def presets
|
|
||||||
Devops::StackPresetsFactory.list
|
|
||||||
end
|
|
||||||
|
|
||||||
def preset id
|
|
||||||
Devops::StackPresetsFactory.get(id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def apply id
|
|
||||||
body = parser.apply
|
|
||||||
preset = Devops::StackPresetsFactory.get(id)
|
|
||||||
stack = preset.create_stack_from_preset(body)
|
|
||||||
stack.owner = owner_from_request
|
|
||||||
Devops::Db.connector.stack_insert(stack)
|
|
||||||
|
|
||||||
file = JobStarter.start_job(:worker, :stack_bootstrap,
|
|
||||||
provider: stack.provider,
|
|
||||||
stack_id: stack.id,
|
|
||||||
request: @request
|
|
||||||
)
|
|
||||||
puts "Syncing report is located here: #{file}"
|
|
||||||
|
|
||||||
stack
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
require_relative "request_parser"
|
|
||||||
|
|
||||||
module Devops
|
|
||||||
module API2_0
|
|
||||||
module Parser
|
|
||||||
class StackPresetParser < RequestParser
|
|
||||||
|
|
||||||
def apply
|
|
||||||
create_object_from_json_body
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
module Devops
|
|
||||||
module API2_0
|
|
||||||
module Routes
|
|
||||||
module StackPresetRoutes
|
|
||||||
|
|
||||||
def self.registered(app)
|
|
||||||
# Get list of available stack_template_presets
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : GET
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* : array of hashes
|
|
||||||
# [ {id: 'preset id', template_preset_body: 'long body'} ]
|
|
||||||
#
|
|
||||||
app.get_with_headers "/stack_presets", :headers => [:accept] do
|
|
||||||
# check_privileges("stack_template_presets", "r")
|
|
||||||
json Devops::API2_0::Handler::StackPreset.new(request).presets.map(&:to_hash)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get information about stack_template_preset
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : GET
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* : hash
|
|
||||||
# {id: 'preset id', template_preset_body: 'long body'}
|
|
||||||
#
|
|
||||||
app.get_with_headers "/stack_presets/:id", :headers => [:accept] do |id|
|
|
||||||
# check_privileges("stack_template_presets", "r")
|
|
||||||
json Devops::API2_0::Handler::StackPreset.new(request).preset(id).to_hash
|
|
||||||
end
|
|
||||||
|
|
||||||
# Build stack template from preset
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : POST
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
# - params :
|
|
||||||
# - provider: string
|
|
||||||
# - stack_template_id: id of stack template to create
|
|
||||||
# - template_attrs: hash with template attributes
|
|
||||||
#
|
|
||||||
# TODO: not stack template, but stack itself
|
|
||||||
#
|
|
||||||
# * *Returns* : created stack template model
|
|
||||||
# {
|
|
||||||
# id: 'template id',
|
|
||||||
# provider: 'provider',
|
|
||||||
# template_body: 'long body'
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
app.post_with_headers "/stack_presets/:id/apply", :headers => [:accept] do |id|
|
|
||||||
# check_privileges("stack_template_presets", "r")
|
|
||||||
check_privileges('stack_template', 'w')
|
|
||||||
stack = Devops::API2_0::Handler::StackPreset.new(request).apply(id)
|
|
||||||
create_response 'Created', stack.to_hash, 201
|
|
||||||
end
|
|
||||||
|
|
||||||
puts "Stack template presets routes initialized"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -22,7 +22,6 @@ module Devops
|
|||||||
|
|
||||||
require_relative "api2/handlers/stack"
|
require_relative "api2/handlers/stack"
|
||||||
require_relative "api2/handlers/stack_template"
|
require_relative "api2/handlers/stack_template"
|
||||||
require_relative "api2/handlers/stack_preset"
|
|
||||||
|
|
||||||
require 'lib/stubber'
|
require 'lib/stubber'
|
||||||
end
|
end
|
||||||
@ -69,7 +68,6 @@ module Devops
|
|||||||
require_relative "api2/routes/bootstrap_templates"
|
require_relative "api2/routes/bootstrap_templates"
|
||||||
require_relative "api2/routes/stack"
|
require_relative "api2/routes/stack"
|
||||||
require_relative "api2/routes/stack_template"
|
require_relative "api2/routes/stack_template"
|
||||||
require_relative "api2/routes/stack_presets"
|
|
||||||
require_relative "api2/routes/statistic"
|
require_relative "api2/routes/statistic"
|
||||||
require_relative "api2/routes/report"
|
require_relative "api2/routes/report"
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@ config[:openstack_ssh_key] = "ssh_key"
|
|||||||
config[:openstack_certificate] = "/path/to/.ssh/openstack.pem"
|
config[:openstack_certificate] = "/path/to/.ssh/openstack.pem"
|
||||||
|
|
||||||
# aws settings
|
# aws settings
|
||||||
|
config[:aws_use_iam_profile] = false
|
||||||
config[:aws_access_key_id] = "access_key_id"
|
config[:aws_access_key_id] = "access_key_id"
|
||||||
config[:aws_secret_access_key] = "secret_access_key"
|
config[:aws_secret_access_key] = "secret_access_key"
|
||||||
config[:aws_ssh_key] = "ssh_key"
|
config[:aws_ssh_key] = "ssh_key"
|
||||||
|
|||||||
@ -13,6 +13,9 @@ module Devops
|
|||||||
set_field_validators :secret_access_key, [::Validators::FieldValidator::NotNil,
|
set_field_validators :secret_access_key, [::Validators::FieldValidator::NotNil,
|
||||||
::Validators::FieldValidator::FieldType::String,
|
::Validators::FieldValidator::FieldType::String,
|
||||||
::Validators::FieldValidator::NotEmpty]
|
::Validators::FieldValidator::NotEmpty]
|
||||||
|
|
||||||
|
set_field_validators :use_iam_profile, [::Validators::FieldValidator::Nil,
|
||||||
|
::Validators::FieldValidator::FieldType::Boolean]
|
||||||
def initialize a={}
|
def initialize a={}
|
||||||
super(a)
|
super(a)
|
||||||
self.provider = Provider::Ec2::PROVIDER
|
self.provider = Provider::Ec2::PROVIDER
|
||||||
@ -45,6 +48,7 @@ module Devops
|
|||||||
{
|
{
|
||||||
access_key_id: "AWS account access key",
|
access_key_id: "AWS account access key",
|
||||||
secret_access_key: "AWS account secret key",
|
secret_access_key: "AWS account secret key",
|
||||||
|
use_iam_profile: "Should use iam profile?",
|
||||||
availability_zone: "Availability zone, todo: remove field?"
|
availability_zone: "Availability zone, todo: remove field?"
|
||||||
}.merge(ProviderAccount::ACCOUNT_FIELDS)
|
}.merge(ProviderAccount::ACCOUNT_FIELDS)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -9,6 +9,7 @@ module Validators
|
|||||||
def validate!
|
def validate!
|
||||||
raise InvalidRecord.new(message) unless valid?
|
raise InvalidRecord.new(message) unless valid?
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
|
puts [e.message, e.backtrace].join("\n")
|
||||||
raise InvalidRecord.new("An error raised during validation with #{self.class}: #{e.class}: #{e.message}")
|
raise InvalidRecord.new("An error raised during validation with #{self.class}: #{e.class}: #{e.message}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,17 @@ module Validators
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class Boolean < FieldType
|
||||||
|
|
||||||
|
def valid?
|
||||||
|
@value == true or @value == false
|
||||||
|
end
|
||||||
|
|
||||||
|
def type_name
|
||||||
|
"boolean"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Array < FieldType
|
class Array < FieldType
|
||||||
|
|
||||||
def type
|
def type
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
require_relative "base"
|
require_relative "base"
|
||||||
|
|
||||||
|
|
||||||
module Validators
|
module Validators
|
||||||
module FieldValidator
|
module FieldValidator
|
||||||
class ProviderAccount < Base
|
class ProviderAccount < Base
|
||||||
|
|
||||||
def valid?
|
def valid?
|
||||||
accounts = AccountsFactory.accounts(@model.provider)
|
accounts = ::Provider::AccountsFactory.accounts(@model.provider)
|
||||||
accounts.map{|a| a.account_name}.include?(@value)
|
accounts.map{|a| a.account_name}.include?(@value)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
require "lib/knife/knife_factory"
|
require "lib/knife/knife_factory"
|
||||||
require "lib/executors/expiration_scheduler"
|
require "lib/executors/expiration_scheduler"
|
||||||
require "hooks"
|
require "hooks"
|
||||||
|
require 'net/ssh'
|
||||||
|
|
||||||
module Devops
|
module Devops
|
||||||
module Executor
|
module Executor
|
||||||
@ -306,14 +307,26 @@ module Devops
|
|||||||
res = delete_from_chef_server(@server.chef_node_name)
|
res = delete_from_chef_server(@server.chef_node_name)
|
||||||
begin
|
begin
|
||||||
new_name = "/etc/chef.backup_#{Time.now.strftime("%d-%m-%Y_%H.%M.%S")}"
|
new_name = "/etc/chef.backup_#{Time.now.strftime("%d-%m-%Y_%H.%M.%S")}"
|
||||||
cmd = "ssh -i #{cert_path} -q #{@server.remote_user}@#{@server.private_ip} \"/bin/sh -c 'if [[ -d /etc/chef ]]; then mv /etc/chef #{new_name}; else echo not found; fi'\""
|
cmd = (@server.remote_user == 'root' ? "" : "sudo ")
|
||||||
DevopsLogger.logger.info("Trying to run command '#{cmd}'")
|
cmd = cmd + "/bin/sh -c 'if [[ -d /etc/chef ]]; then mv /etc/chef #{new_name} && echo ok; else echo not found; fi'"
|
||||||
r = execute_system_command(cmd).strip
|
DevopsLogger.logger.info("SSH: trying to run command '#{cmd}'")
|
||||||
if r == 'not found'
|
Net::SSH.start(@server.private_ip, @server.remote_user, :keys => [cert_path]) do |session|
|
||||||
res[:server] = "Directory '/etc/chef' does not exists"
|
session.open_channel do |channel|
|
||||||
else
|
channel.request_pty(:modes => { Net::SSH::Connection::Term::ECHO => 0 }) do |c, success|
|
||||||
raise(r) unless last_command_successful?
|
raise "could not request pty" unless success
|
||||||
res[:server] = "'/etc/chef' renamed to '#{new_name}'"
|
channel.exec cmd
|
||||||
|
channel.on_data do |c_, data|
|
||||||
|
if data == 'not found'
|
||||||
|
res[:server] = "Directory '/etc/chef' does not exists"
|
||||||
|
elsif data == 'ok'
|
||||||
|
res[:server] = "'/etc/chef' renamed to '#{new_name}'"
|
||||||
|
else
|
||||||
|
DevopsLogger.logger.error "Unexpected error: " + data
|
||||||
|
raise(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
rescue => e
|
rescue => e
|
||||||
DevopsLogger.logger.error "Unbootstrap error: " + e.message
|
DevopsLogger.logger.error "Unbootstrap error: " + e.message
|
||||||
|
|||||||
@ -1,75 +0,0 @@
|
|||||||
require 'db/mongo/models/stack_template/stack_template_factory'
|
|
||||||
|
|
||||||
module Devops
|
|
||||||
module StackPresets
|
|
||||||
class Base
|
|
||||||
|
|
||||||
def id
|
|
||||||
self.class.to_s.underscore_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
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
require_relative 'base'
|
|
||||||
require_relative 'postgres_cluster'
|
|
||||||
require_relative 'preset_not_found'
|
|
||||||
|
|
||||||
class Devops::StackPresetsFactory
|
|
||||||
|
|
||||||
# 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::StackPresets.constants.select do |class_name|
|
|
||||||
class_name != :Base
|
|
||||||
end.map do |class_name|
|
|
||||||
Devops::StackPresets.const_get(class_name).new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.get(id)
|
|
||||||
preset = list.detect { |preset| preset.id == id }
|
|
||||||
raise PresetNotFound, "Preset '#{preset}' not found" unless preset
|
|
||||||
preset
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
module Devops::StackPresets
|
|
||||||
class PostgresCluster < Base
|
|
||||||
def template_file_extension
|
|
||||||
:yml
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
heat_template_version: 2013-05-23
|
|
||||||
|
|
||||||
description: Simple template to deploy a single compute instance
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
key_name:
|
|
||||||
type: string
|
|
||||||
label: Key Name
|
|
||||||
description: Name of key-pair to be used for compute instance
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
key_name: { get_param: key_name }
|
|
||||||
image: 5f4020a1-b6ab-47e4-a0ed-de4324a17c3a
|
|
||||||
flavor: m1.micro
|
|
||||||
networks:
|
|
||||||
- network: devops-net-1
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
class PresetNotFound < StandardError
|
|
||||||
|
|
||||||
end
|
|
||||||
@ -15,10 +15,14 @@ module Provider
|
|||||||
self.certificate_path = config[:aws_certificate]
|
self.certificate_path = config[:aws_certificate]
|
||||||
self.ssh_key = config[:aws_ssh_key]
|
self.ssh_key = config[:aws_ssh_key]
|
||||||
options = {
|
options = {
|
||||||
:provider => "aws",
|
:provider => "aws"
|
||||||
:aws_access_key_id => config[:aws_access_key_id],
|
|
||||||
:aws_secret_access_key => config[:aws_secret_access_key]
|
|
||||||
}
|
}
|
||||||
|
if config[:aws_use_iam_profile]
|
||||||
|
options[:use_iam_profile] = true
|
||||||
|
else
|
||||||
|
options[:aws_access_key_id] = config[:aws_access_key_id]
|
||||||
|
options[:aws_secret_access_key] = config[:aws_secret_access_key]
|
||||||
|
end
|
||||||
if config[:aws_proxy] and config[:aws_no_proxy]
|
if config[:aws_proxy] and config[:aws_no_proxy]
|
||||||
options[:connection_options] = {
|
options[:connection_options] = {
|
||||||
:proxy => config[:aws_proxy],
|
:proxy => config[:aws_proxy],
|
||||||
@ -52,7 +56,7 @@ module Provider
|
|||||||
end
|
end
|
||||||
|
|
||||||
def groups filters={}
|
def groups filters={}
|
||||||
g = self.compute.describe_security_groups(filters)
|
g = self.compute.describe_security_groups(filters || {})
|
||||||
convert_groups(g.body["securityGroupInfo"])
|
convert_groups(g.body["securityGroupInfo"])
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -257,8 +261,9 @@ module Provider
|
|||||||
end
|
end
|
||||||
|
|
||||||
def validate_stack_template template
|
def validate_stack_template template
|
||||||
r = cloud_formation.validate_template({'TemplateBody' => template})
|
#r = cloud_formation.validate_template({'TemplateBody' => template})
|
||||||
pp r.body
|
#pp r.body
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_stack(stack)
|
def delete_stack(stack)
|
||||||
|
|||||||
@ -20,6 +20,7 @@ module Provider
|
|||||||
aws_ssh_key: account.ssh_key,
|
aws_ssh_key: account.ssh_key,
|
||||||
aws_access_key_id: account.access_key_id,
|
aws_access_key_id: account.access_key_id,
|
||||||
aws_secret_access_key: account.secret_access_key,
|
aws_secret_access_key: account.secret_access_key,
|
||||||
|
aws_use_iam_profile: account.use_iam_profile,
|
||||||
aws_availability_zone: account.availability_zone,
|
aws_availability_zone: account.availability_zone,
|
||||||
|
|
||||||
aws_proxy: config[:aws_proxy],
|
aws_proxy: config[:aws_proxy],
|
||||||
|
|||||||
@ -94,7 +94,6 @@ templates = {
|
|||||||
|
|
||||||
#list
|
#list
|
||||||
"templates/api_v2/00_list/flavor.feature.erb" => "features/api_v2/00_list/flavor.feature",
|
"templates/api_v2/00_list/flavor.feature.erb" => "features/api_v2/00_list/flavor.feature",
|
||||||
"templates/api_v2/00_list/stack_preset.feature.erb" => "features/api_v2/00_list/stack_preset.feature",
|
|
||||||
"templates/api_v2/00_list/00_network.feature.erb" => "features/api_v2/00_list/00_network.feature",
|
"templates/api_v2/00_list/00_network.feature.erb" => "features/api_v2/00_list/00_network.feature",
|
||||||
"templates/api_v2/00_list/10_user.feature.erb" => "features/api_v2/00_list/10_user.feature",
|
"templates/api_v2/00_list/10_user.feature.erb" => "features/api_v2/00_list/10_user.feature",
|
||||||
"templates/api_v2/00_list/10_group.feature.erb" => "features/api_v2/00_list/10_group.feature",
|
"templates/api_v2/00_list/10_group.feature.erb" => "features/api_v2/00_list/10_group.feature",
|
||||||
|
|||||||
@ -1,28 +0,0 @@
|
|||||||
@stack_preset @list
|
|
||||||
Feature: stack template preset list
|
|
||||||
|
|
||||||
Scenario: Get list of all stack template presets
|
|
||||||
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
|
|
||||||
And response array should contains elements like:
|
|
||||||
"""
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"id": "test",
|
|
||||||
"template_body": "long body"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
"""
|
|
||||||
|
|
||||||
Scenario: Get information about particular stack template preset
|
|
||||||
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_body": "long body"
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
Loading…
Reference in New Issue
Block a user