Merge branch 'qa' into specs
This commit is contained in:
commit
68c4ff03e7
@ -71,7 +71,7 @@ class Server < Handler
|
|||||||
:deploy_env => @args[3]
|
:deploy_env => @args[3]
|
||||||
}
|
}
|
||||||
|
|
||||||
[:key, :without_bootstrap, :name, :groups, :force].each do |k|
|
[:key, :without_bootstrap, :name, :groups, :force, :private_ip].each do |k|
|
||||||
q[k] = self.options[k] unless self.options[k].nil?
|
q[k] = self.options[k] unless self.options[k].nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ class DeployOptions < CommonOptions
|
|||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.banner
|
parser.banner << self.banner
|
||||||
|
|
||||||
parser.recognize_option_value(:tag, 'deploy', variable_name: 'TAG1,TAG2...') do |tags|
|
parser.recognize_option_value(:tag, resource_name: :deploy, variable_name: 'TAG1,TAG2...') do |tags|
|
||||||
options[:tags] = tags.split(",")
|
options[:tags] = tags.split(",")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ module Options
|
|||||||
class DevopsOptionsParser
|
class DevopsOptionsParser
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
attr_reader :parsed_options
|
attr_reader :parsed_options
|
||||||
|
attr_accessor :resource_name, :command_name
|
||||||
|
|
||||||
# leave this duplication for a while
|
# leave this duplication for a while
|
||||||
TABLE_FORMAT = "table"
|
TABLE_FORMAT = "table"
|
||||||
@ -46,8 +47,9 @@ module Options
|
|||||||
# it is used to set options values without later quiz.
|
# it is used to set options values without later quiz.
|
||||||
# Arguments description:
|
# Arguments description:
|
||||||
# option_name - name of option;
|
# option_name - name of option;
|
||||||
# resource_name - used for description lookup. Lookup path is "options.descriptions.#{resource_name}.#{option_name}".
|
|
||||||
# attrs - hash with following options:
|
# attrs - hash with following options:
|
||||||
|
# :resource_name - used for description lookup. Could be set with attr_accessor. Lookup path is "options.descriptions.#{resource_name}.#{option_name}".
|
||||||
|
# :command_name - Also could be set with attr_accessor. Changes description lookup to "options.descriptions.#{resource_name}.#{command_name}.#{option_name}"
|
||||||
# :type - could be one of following values:
|
# :type - could be one of following values:
|
||||||
# :required (default)
|
# :required (default)
|
||||||
# :optional
|
# :optional
|
||||||
@ -57,19 +59,22 @@ module Options
|
|||||||
# :option_key - key in result_options hash. Default - option_name.to_sym
|
# :option_key - key in result_options hash. Default - option_name.to_sym
|
||||||
# :variable - default - option_name.upcase
|
# :variable - default - option_name.upcase
|
||||||
# :description - default - I18n.t("options.descriptions.#{resource_name}.#{option_name}")
|
# :description - default - I18n.t("options.descriptions.#{resource_name}.#{option_name}")
|
||||||
# :i18n_scope - if present, change I18n lookup path to "options.descriptions.#{resource_name}.#{i18n_scope}.#{option_name}"
|
|
||||||
# :short - short option name
|
# :short - short option name
|
||||||
#
|
#
|
||||||
# EXAMPLES:
|
# EXAMPLES:
|
||||||
# 1)
|
# 1)
|
||||||
# parser.recognize_option_value(:provider, 'stack')
|
# parser.resource_name = :stack
|
||||||
|
# parser.recognize_option_value(:provider)
|
||||||
# is equal to
|
# is equal to
|
||||||
# opts.on("--provider provider", I18n.t("options.descriptions.stack.provider)) do |provider|
|
# opts.on("--provider provider", I18n.t("options.descriptions.stack.provider)) do |provider|
|
||||||
# options[:provider] = provider
|
# options[:provider] = provider
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
|
# Also, you could pass resource name in attributes without need to use attr_accessor:
|
||||||
|
# parser.recognize_option_value(:provider, resource_name: :stack)
|
||||||
|
#
|
||||||
# 2)
|
# 2)
|
||||||
# parser.recognize_option_value(:provider, 'stack', type: :optional, default: 'openstack')
|
# parser.recognize_option_value(:provider, type: :optional, default: 'openstack')
|
||||||
# is equal to
|
# is equal to
|
||||||
# options[:provider] = 'openstack'
|
# options[:provider] = 'openstack'
|
||||||
# opts.on("--provider [provider]", I18n.t("options.descriptions.stack.provider)) do |provider|
|
# opts.on("--provider [provider]", I18n.t("options.descriptions.stack.provider)) do |provider|
|
||||||
@ -77,7 +82,7 @@ module Options
|
|||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# 3)
|
# 3)
|
||||||
# parser.recognize_option_value(:no_template, 'image', type: :switch, default: false, switch_value: true)
|
# parser.recognize_option_value(:no_template, type: :switch, default: false, switch_value: true)
|
||||||
# is equal to
|
# is equal to
|
||||||
# options[:no_template] = false
|
# options[:no_template] = false
|
||||||
# opts.on("--no_template", I18n.t("options.descriptions.image.no_template)) do
|
# opts.on("--no_template", I18n.t("options.descriptions.image.no_template)) do
|
||||||
@ -85,20 +90,28 @@ module Options
|
|||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# 4)
|
# 4)
|
||||||
# parser.recognize_option_value(:parameters, 'stack') do |parameters|
|
# parser.recognize_option_value(:parameters) do |parameters|
|
||||||
# options[:parameters] = JSON.parse(parameters)
|
# options[:parameters] = JSON.parse(parameters)
|
||||||
# end
|
# end
|
||||||
# is equal to
|
# is equal to
|
||||||
# opts.on("--parameters parameters", I18n.t("options.descriptions.stack.parameters)) do |parameters|
|
# opts.on("--parameters parameters", I18n.t("options.descriptions.stack.parameters)) do |parameters|
|
||||||
# options[:parameters] = JSON.parse(parameters)
|
# options[:parameters] = JSON.parse(parameters)
|
||||||
# end
|
# end
|
||||||
def recognize_option_value(option_name, resource_name, attrs={}, &block)
|
def recognize_option_value(option_name, attrs={}, &block)
|
||||||
recognizer = OptionValueRecognizer.new(option_name, resource_name, attrs)
|
scope = i18n_scope(attrs.delete(:resource_name), attrs.delete(:command_name), option_name)
|
||||||
|
recognizer = OptionValueRecognizer.new(option_name, scope, attrs)
|
||||||
recognizer.recognize(@parser, @parsed_options, &block)
|
recognizer.recognize(@parser, @parsed_options, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def i18n_scope(specified_resource_name, specified_command_name, option_name)
|
||||||
|
resource = specified_resource_name || resource_name
|
||||||
|
raise "Resource name isn't specified. Use parser.resource= or :resource_name attribute" unless resource
|
||||||
|
segments = [:options, :descriptions, resource, specified_command_name || command_name, option_name]
|
||||||
|
segments.compact.join('.')
|
||||||
|
end
|
||||||
|
|
||||||
def banner_usage
|
def banner_usage
|
||||||
@parser.banner = "\n" + I18n.t("options.usage", :cmd => $0) + "\n\n" + I18n.t("options.commands") + ":\n"
|
@parser.banner = "\n" + I18n.t("options.usage", :cmd => $0) + "\n\n" + I18n.t("options.commands") + ":\n"
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3,14 +3,16 @@
|
|||||||
# Description and examples of usage are in devops_option_parser.rb.
|
# Description and examples of usage are in devops_option_parser.rb.
|
||||||
class OptionValueRecognizer
|
class OptionValueRecognizer
|
||||||
|
|
||||||
def initialize(option_name, resource_name, attrs={})
|
attr_reader :option_name, :i18n_scope, :attrs
|
||||||
@option_name, @attrs = option_name, attrs
|
|
||||||
|
|
||||||
set_type(option_name, resource_name)
|
def initialize(option_name, i18n_scope, attrs={})
|
||||||
set_option_key(option_name, resource_name)
|
@option_name, @i18n_scope, @attrs = option_name, i18n_scope, attrs
|
||||||
set_description(option_name, resource_name)
|
|
||||||
set_variable(option_name, resource_name)
|
set_type
|
||||||
set_options_to_recognize(option_name, resource_name)
|
set_option_key
|
||||||
|
set_description
|
||||||
|
set_variable
|
||||||
|
set_options_to_recognize
|
||||||
end
|
end
|
||||||
|
|
||||||
def recognize(parser, parsed_options, &block)
|
def recognize(parser, parsed_options, &block)
|
||||||
@ -29,7 +31,9 @@ class OptionValueRecognizer
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_type(option_name, resource_name)
|
|
||||||
|
|
||||||
|
def set_type
|
||||||
@type = @attrs[:type] || :required
|
@type = @attrs[:type] || :required
|
||||||
raise "Illegal optional type: '#{@type}'" unless [:required, :optional, :switch].include?(@type)
|
raise "Illegal optional type: '#{@type}'" unless [:required, :optional, :switch].include?(@type)
|
||||||
if @type == :switch && !@attrs.keys.include?(:switch_value)
|
if @type == :switch && !@attrs.keys.include?(:switch_value)
|
||||||
@ -37,22 +41,15 @@ class OptionValueRecognizer
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_option_key(option_name, resource_name)
|
def set_option_key
|
||||||
@option_key = @attrs[:option_key] || option_name.to_sym
|
@option_key = @attrs[:option_key] || option_name.to_sym
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_description(option_name, resource_name)
|
def set_description
|
||||||
if @attrs[:description]
|
@description = @attrs[:description] || I18n.t(i18n_scope)
|
||||||
@description = @attrs[:description]
|
|
||||||
else
|
|
||||||
lookup_path = [:options, :descriptions, resource_name]
|
|
||||||
lookup_path << @attrs[:i18n_scope] if @attrs[:i18n_scope]
|
|
||||||
lookup_path << option_name
|
|
||||||
@description = I18n.t(lookup_path.join('.'))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_variable(option_name, resource_name)
|
def set_variable
|
||||||
variable = @attrs[:variable] || option_name.upcase
|
variable = @attrs[:variable] || option_name.upcase
|
||||||
|
|
||||||
@variable = case @type
|
@variable = case @type
|
||||||
@ -65,7 +62,7 @@ class OptionValueRecognizer
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_options_to_recognize(option_name, resource_name)
|
def set_options_to_recognize
|
||||||
full = "--#{@option_name}#{@variable}"
|
full = "--#{@option_name}#{@variable}"
|
||||||
@options_to_recognize = [full]
|
@options_to_recognize = [full]
|
||||||
@options_to_recognize.unshift(@attrs[:short]) if @attrs[:short]
|
@options_to_recognize.unshift(@attrs[:short]) if @attrs[:short]
|
||||||
|
|||||||
@ -17,12 +17,13 @@ class ImageOptions < CommonOptions
|
|||||||
def create_options
|
def create_options
|
||||||
self.options do |parser, options|
|
self.options do |parser, options|
|
||||||
parser.banner << self.create_banner
|
parser.banner << self.create_banner
|
||||||
|
parser.resource_name = :image
|
||||||
|
|
||||||
parser.recognize_option_value(:provider, 'image')
|
parser.recognize_option_value(:provider)
|
||||||
parser.recognize_option_value(:image_id, 'image')
|
parser.recognize_option_value(:image_id)
|
||||||
parser.recognize_option_value(:ssh_username, 'image')
|
parser.recognize_option_value(:ssh_username)
|
||||||
parser.recognize_option_value(:bootstrap_template, 'image')
|
parser.recognize_option_value(:bootstrap_template)
|
||||||
parser.recognize_option_value(:no_bootstrap_template, 'image', type: :switch, switch_value: true, default: false)
|
parser.recognize_option_value(:no_bootstrap_template, type: :switch, switch_value: true, default: false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -29,31 +29,32 @@ class ProjectOptions < CommonOptions
|
|||||||
def create_options
|
def create_options
|
||||||
self.options do |parser, options|
|
self.options do |parser, options|
|
||||||
parser.banner << self.create_banner
|
parser.banner << self.create_banner
|
||||||
|
parser.resource_name = :project
|
||||||
|
|
||||||
parser.recognize_option_value(:groups, 'project', variable: 'GROUP_1,GROUP_2...') do |groups|
|
parser.recognize_option_value(:groups, variable: 'GROUP_1,GROUP_2...') do |groups|
|
||||||
options[:groups] = groups.split(",")
|
options[:groups] = groups.split(",")
|
||||||
end
|
end
|
||||||
|
|
||||||
parser.recognize_option_value(:file, 'project') do |file|
|
parser.recognize_option_value(:file) do |file|
|
||||||
abort("File '#{file}' does not exist") unless File.exist?(file)
|
abort("File '#{file}' does not exist") unless File.exist?(file)
|
||||||
options[:file] = file
|
options[:file] = file
|
||||||
end
|
end
|
||||||
|
|
||||||
parser.recognize_option_value(:subnets, 'project', variable: 'SUBNET_1,SUBNET_2...') do |subnets|
|
parser.recognize_option_value(:subnets, variable: 'SUBNET_1,SUBNET_2...') do |subnets|
|
||||||
options[:subnets] = subnets.split(",")
|
options[:subnets] = subnets.split(",")
|
||||||
end
|
end
|
||||||
|
|
||||||
parser.recognize_option_value(:users, 'project', variable: 'USER_1,USER_2...') do |users|
|
parser.recognize_option_value(:users, variable: 'USER_1,USER_2...') do |users|
|
||||||
options[:users] = Set.new(users.split(","))
|
options[:users] = Set.new(users.split(","))
|
||||||
end
|
end
|
||||||
|
|
||||||
parser.recognize_option_value(:deploy_env, 'project', option_key: :identifier)
|
parser.recognize_option_value(:deploy_env, option_key: :identifier)
|
||||||
parser.recognize_option_value(:flavor, 'project')
|
parser.recognize_option_value(:flavor)
|
||||||
parser.recognize_option_value(:image, 'project')
|
parser.recognize_option_value(:image)
|
||||||
parser.recognize_option_value(:run_list, 'project')
|
parser.recognize_option_value(:run_list)
|
||||||
parser.recognize_option_value(:provider, 'project')
|
parser.recognize_option_value(:provider)
|
||||||
parser.recognize_option_value(:no_expires, 'project', type: :switch, switch_value: true, default: false)
|
parser.recognize_option_value(:no_expires, type: :switch, switch_value: true, default: false)
|
||||||
parser.recognize_option_value(:expires, 'project')
|
parser.recognize_option_value(:expires)
|
||||||
|
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
@ -72,7 +73,7 @@ class ProjectOptions < CommonOptions
|
|||||||
self.options do |parser, options|
|
self.options do |parser, options|
|
||||||
parser.banner << self.user_add_banner
|
parser.banner << self.user_add_banner
|
||||||
|
|
||||||
parser.recognize_option_value(:deploy_env, 'project', i18n_scope: 'user_add')
|
parser.recognize_option_value(:deploy_env, resource_name: :project, command_name: 'user_add')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ class ProjectOptions < CommonOptions
|
|||||||
self.options do |parser, options|
|
self.options do |parser, options|
|
||||||
parser.banner << self.user_delete_banner
|
parser.banner << self.user_delete_banner
|
||||||
|
|
||||||
parser.recognize_option_value(:deploy_env, 'project', i18n_scope: 'user_delete')
|
parser.recognize_option_value(:deploy_env, resource_name: :project, command_name: 'user_delete')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ class ProjectOptions < CommonOptions
|
|||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.deploy_banner
|
parser.banner << self.deploy_banner
|
||||||
|
|
||||||
parser.recognize_option_value(:servers, 'project', i18n_scope: 'deploy') do |servers|
|
parser.recognize_option_value(:servers, resource_name: :project, command_name: 'deploy') do |servers|
|
||||||
options[:servers] = servers.split(",")
|
options[:servers] = servers.split(",")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -96,7 +97,7 @@ class ProjectOptions < CommonOptions
|
|||||||
|
|
||||||
def delete_servers_options
|
def delete_servers_options
|
||||||
self.options do |parser, options|
|
self.options do |parser, options|
|
||||||
parser.recognize_option_value(:dry_run, 'project', type: :switch, default: false, switch_value: true, i18n_scope: 'delete_servers')
|
parser.recognize_option_value(:dry_run, resource_name: :project, type: :switch, default: false, switch_value: true, command_name: 'delete_servers')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ class ScriptOptions < CommonOptions
|
|||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.delete_banner
|
parser.banner << self.delete_banner
|
||||||
|
|
||||||
parser.recognize_option_value(:params, 'script') do |params|
|
parser.recognize_option_value(:params, resource_name: :script) do |params|
|
||||||
options[:params] = params.split(",")
|
options[:params] = params.split(",")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -24,22 +24,21 @@ class ServerOptions < CommonOptions
|
|||||||
def delete_options
|
def delete_options
|
||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.delete_banner
|
parser.banner << self.delete_banner
|
||||||
|
parser.resource_name = :server
|
||||||
|
parser.command_name = :delete
|
||||||
|
|
||||||
parser.recognize_option_value(:instance, 'server',
|
parser.recognize_option_value(:instance,
|
||||||
type: :switch,
|
type: :switch,
|
||||||
default: 'node',
|
default: 'node',
|
||||||
switch_value: 'instance',
|
switch_value: 'instance',
|
||||||
option_key: :key,
|
option_key: :key
|
||||||
i18n_scope: 'delete'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.recognize_option_value(:no_ask, 'server',
|
parser.recognize_option_value(:no_ask,
|
||||||
type: :switch,
|
type: :switch,
|
||||||
default: false,
|
default: false,
|
||||||
switch_value: true,
|
switch_value: true
|
||||||
i18n_scope: 'delete'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -47,12 +46,13 @@ class ServerOptions < CommonOptions
|
|||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.delete_banner
|
parser.banner << self.delete_banner
|
||||||
|
|
||||||
parser.recognize_option_value(:instance, 'server',
|
parser.recognize_option_value(:instance,
|
||||||
|
resource_name: :server,
|
||||||
|
command_name: :pause,
|
||||||
type: :switch,
|
type: :switch,
|
||||||
default: 'node',
|
default: 'node',
|
||||||
switch_value: 'instance',
|
switch_value: 'instance',
|
||||||
option_key: :key,
|
option_key: :key
|
||||||
i18n_scope: 'pause'
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -61,12 +61,13 @@ class ServerOptions < CommonOptions
|
|||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.delete_banner
|
parser.banner << self.delete_banner
|
||||||
|
|
||||||
parser.recognize_option_value(:instance, 'server',
|
parser.recognize_option_value(:instance,
|
||||||
|
resource_name: :server,
|
||||||
|
command_name: :unpause,
|
||||||
type: :switch,
|
type: :switch,
|
||||||
default: 'node',
|
default: 'node',
|
||||||
switch_value: 'instance',
|
switch_value: 'instance',
|
||||||
option_key: :key,
|
option_key: :key
|
||||||
i18n_scope: 'unpause'
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -75,12 +76,13 @@ class ServerOptions < CommonOptions
|
|||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.delete_banner
|
parser.banner << self.delete_banner
|
||||||
|
|
||||||
parser.recognize_option_value(:instance, 'server',
|
parser.recognize_option_value(:instance,
|
||||||
|
resource_name: :server,
|
||||||
|
command_name: :reserve,
|
||||||
type: :switch,
|
type: :switch,
|
||||||
default: 'node',
|
default: 'node',
|
||||||
switch_value: 'instance',
|
switch_value: 'instance',
|
||||||
option_key: :key,
|
option_key: :key
|
||||||
i18n_scope: 'reserve'
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -89,12 +91,13 @@ class ServerOptions < CommonOptions
|
|||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.delete_banner
|
parser.banner << self.delete_banner
|
||||||
|
|
||||||
parser.recognize_option_value(:instance, 'server',
|
parser.recognize_option_value(:instance,
|
||||||
|
resource_name: :server,
|
||||||
|
command_name: :unreserve,
|
||||||
type: :switch,
|
type: :switch,
|
||||||
default: 'node',
|
default: 'node',
|
||||||
switch_value: 'instance',
|
switch_value: 'instance',
|
||||||
option_key: :key,
|
option_key: :key
|
||||||
i18n_scope: 'unreserve'
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -102,26 +105,29 @@ class ServerOptions < CommonOptions
|
|||||||
def create_options
|
def create_options
|
||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.create_banner
|
parser.banner << self.create_banner
|
||||||
|
parser.resource_name = :server
|
||||||
|
parser.command_name = :create
|
||||||
|
|
||||||
parser.recognize_option_value('without_bootstrap', 'server',
|
parser.recognize_option_value('without_bootstrap',
|
||||||
type: :switch,
|
type: :switch,
|
||||||
switch_value: true,
|
switch_value: true,
|
||||||
option_key: :without_bootstrap,
|
option_key: :without_bootstrap,
|
||||||
i18n_scope: 'create'
|
i18n_scope: 'create'
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.recognize_option_value(:name, 'server', short: '-N', i18n_scope: 'create')
|
parser.recognize_option_value(:name, short: '-N')
|
||||||
parser.recognize_option_value(:force, 'server', short: '-f', i18n_scope: 'create')
|
parser.recognize_option_value(:force, short: '-f')
|
||||||
parser.recognize_option_value(:key, 'server', i18n_scope: 'create')
|
parser.recognize_option_value(:key)
|
||||||
|
|
||||||
parser.recognize_option_value(:groups, 'server',
|
parser.recognize_option_value(:groups,
|
||||||
short: '-G',
|
short: '-G',
|
||||||
variable: 'GROUP_1,GROUP_2...',
|
variable: 'GROUP_1,GROUP_2...'
|
||||||
i18n_scope: 'create'
|
|
||||||
) do |groups|
|
) do |groups|
|
||||||
options[:groups] = groups.split(",")
|
options[:groups] = groups.split(",")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
parser.recognize_option_value(:private_ip, 'server', short: '-N', i18n_scope: 'create')
|
||||||
|
|
||||||
# it was disabled somewhy
|
# it was disabled somewhy
|
||||||
# parser.on('--public-ip', "Associate public IP with server") do
|
# parser.on('--public-ip', "Associate public IP with server") do
|
||||||
# options[:public_ip] = true
|
# options[:public_ip] = true
|
||||||
@ -132,10 +138,12 @@ class ServerOptions < CommonOptions
|
|||||||
def bootstrap_options
|
def bootstrap_options
|
||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.bootstrap_banner
|
parser.banner << self.bootstrap_banner
|
||||||
|
parser.resource_name = :server
|
||||||
|
parser.command_name = :bootstrap
|
||||||
|
|
||||||
parser.recognize_option_value(:name, 'server', short: '-N', i18n_scope: 'bootstrap')
|
parser.recognize_option_value(:name, short: '-N')
|
||||||
parser.recognize_option_value(:bootstrap_template, 'server', i18n_scope: 'bootstrap')
|
parser.recognize_option_value(:bootstrap_template)
|
||||||
parser.recognize_option_value(:run_list, 'server', i18n_scope: 'bootstrap') do |list|
|
parser.recognize_option_value(:run_list) do |list|
|
||||||
options[:run_list] = list.split(",")
|
options[:run_list] = list.split(",")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -145,7 +153,7 @@ class ServerOptions < CommonOptions
|
|||||||
options do |parser, options|
|
options do |parser, options|
|
||||||
parser.banner << self.add_banner
|
parser.banner << self.add_banner
|
||||||
|
|
||||||
parser.recognize_option_value('public-ip', 'server', i18n_scope: 'add', option_key: :public_ip)
|
parser.recognize_option_value('public-ip', resource_name: :server, command_name: :add, option_key: :public_ip)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -21,16 +21,16 @@ class StackOptions < CommonOptions
|
|||||||
def create_options
|
def create_options
|
||||||
self.options do |parser, options|
|
self.options do |parser, options|
|
||||||
parser.banner << self.create_banner
|
parser.banner << self.create_banner
|
||||||
|
parser.resource_name = :stack
|
||||||
|
|
||||||
parser.recognize_option_value(:provider, 'stack')
|
parser.recognize_option_value(:provider)
|
||||||
parser.recognize_option_value(:id, 'stack')
|
parser.recognize_option_value(:id)
|
||||||
parser.recognize_option_value(:project, 'stack')
|
parser.recognize_option_value(:project)
|
||||||
parser.recognize_option_value(:deploy_env, 'stack')
|
parser.recognize_option_value(:deploy_env)
|
||||||
parser.recognize_option_value(:stack_template, 'stack')
|
parser.recognize_option_value(:stack_template)
|
||||||
parser.recognize_option_value(:parameters_file, 'stack')
|
parser.recognize_option_value(:parameters_file)
|
||||||
parser.recognize_option_value(:run_list, 'stack')
|
parser.recognize_option_value(:run_list)
|
||||||
parser.recognize_option_value(:without_bootstrap, 'stack', type: :switch, switch_value: true)
|
parser.recognize_option_value(:without_bootstrap, type: :switch, switch_value: true)
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -17,10 +17,11 @@ class StackTemplateOptions < CommonOptions
|
|||||||
def create_options
|
def create_options
|
||||||
self.options do |parser, options|
|
self.options do |parser, options|
|
||||||
parser.banner << self.create_banner
|
parser.banner << self.create_banner
|
||||||
|
parser.resource_name = :stack_template
|
||||||
|
|
||||||
parser.recognize_option_value(:provider, 'stack_template', default: nil)
|
parser.recognize_option_value(:provider, default: nil)
|
||||||
parser.recognize_option_value(:id, 'stack_template')
|
parser.recognize_option_value(:id)
|
||||||
parser.recognize_option_value(:template_file, 'stack_template')
|
parser.recognize_option_value(:template_file)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ class UserOptions < CommonOptions
|
|||||||
self.options do |parser, options|
|
self.options do |parser, options|
|
||||||
parser.banner << self.create_banner
|
parser.banner << self.create_banner
|
||||||
|
|
||||||
parser.recognize_option_value(:new_password, 'user')
|
parser.recognize_option_value(:new_password, resource_name: :user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -349,11 +349,12 @@ en:
|
|||||||
unreserve:
|
unreserve:
|
||||||
instance: Unreserve server by instance id
|
instance: Unreserve server by instance id
|
||||||
create:
|
create:
|
||||||
without-bootstrap: 'Run server without bootsraping phase'
|
without_bootstrap: 'Run server without bootsraping phase'
|
||||||
name: Set node name
|
name: Set node name
|
||||||
groups: The security groups for this server
|
groups: The security groups for this server
|
||||||
force: Cancel rollback operation on error
|
force: Cancel rollback operation on error
|
||||||
key: User another key for server
|
key: User another key for server
|
||||||
|
private_ip: Private ip for this server
|
||||||
bootstrap:
|
bootstrap:
|
||||||
name: Set chef name
|
name: Set chef name
|
||||||
bootstrap_template: Bootstrap template
|
bootstrap_template: Bootstrap template
|
||||||
@ -366,7 +367,9 @@ en:
|
|||||||
deploy_env: Deploy env
|
deploy_env: Deploy env
|
||||||
project: Stack project
|
project: Stack project
|
||||||
stack_template: Stack template
|
stack_template: Stack template
|
||||||
parameters: Parameters hash as single quoted JSON string
|
parameters_file: File with parameters JSON
|
||||||
|
run_list: Stack run list
|
||||||
|
without_bootstrap: Skip bootsraping phase on created instances
|
||||||
stack_template:
|
stack_template:
|
||||||
provider: Stack template provider
|
provider: Stack template provider
|
||||||
id: Stack template id
|
id: Stack template id
|
||||||
|
|||||||
@ -196,6 +196,7 @@ module Devops
|
|||||||
# "force": null, -> do not delete server on error
|
# "force": null, -> do not delete server on error
|
||||||
# "groups": [], -> specify special security groups, overrides value from project env
|
# "groups": [], -> specify special security groups, overrides value from project env
|
||||||
# "key": "ssh key" -> specify ssh key for server, overrides value from project env
|
# "key": "ssh key" -> specify ssh key for server, overrides value from project env
|
||||||
|
# "private_ip": null -> should be string like "172.31.31.203" if present
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# * *Returns* : text stream
|
# * *Returns* : text stream
|
||||||
|
|||||||
@ -23,13 +23,13 @@ module Devops
|
|||||||
set_field_validators :id, [::Validators::FieldValidator::NotNil,
|
set_field_validators :id, [::Validators::FieldValidator::NotNil,
|
||||||
::Validators::FieldValidator::FieldType::String,
|
::Validators::FieldValidator::FieldType::String,
|
||||||
::Validators::FieldValidator::NotEmpty,
|
::Validators::FieldValidator::NotEmpty,
|
||||||
::Validators::FieldValidator::ImageName,
|
::Validators::FieldValidator::ImageId,
|
||||||
::Validators::Image::ImageInFilter]
|
::Validators::Image::ImageInFilter]
|
||||||
|
|
||||||
set_field_validators :remote_user, [::Validators::FieldValidator::NotNil,
|
set_field_validators :remote_user, [::Validators::FieldValidator::NotNil,
|
||||||
::Validators::FieldValidator::FieldType::String,
|
::Validators::FieldValidator::FieldType::String,
|
||||||
::Validators::FieldValidator::NotEmpty,
|
::Validators::FieldValidator::NotEmpty,
|
||||||
::Validators::FieldValidator::ImageName]
|
::Validators::FieldValidator::ImageUsername]
|
||||||
|
|
||||||
set_field_validators :name, [::Validators::FieldValidator::NotNil,
|
set_field_validators :name, [::Validators::FieldValidator::NotNil,
|
||||||
::Validators::FieldValidator::FieldType::String,
|
::Validators::FieldValidator::FieldType::String,
|
||||||
|
|||||||
18
devops-service/db/validators/field_validators/image_id.rb
Normal file
18
devops-service/db/validators/field_validators/image_id.rb
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
require_relative "base"
|
||||||
|
module Validators
|
||||||
|
module FieldValidator
|
||||||
|
class ImageId < Base
|
||||||
|
|
||||||
|
MAX_LEN = 100
|
||||||
|
NAME_REGEX = /\A[\w\-\.]{1,#{MAX_LEN}}\z/
|
||||||
|
|
||||||
|
def valid?
|
||||||
|
!NAME_REGEX.match(@value).nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def message
|
||||||
|
"Invalid value '#{@value}': it should contains symbols 'a-zA-Z0-9_-.' and length should be more then 1 and less or equals then #{MAX_LEN}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -3,15 +3,14 @@ module Validators
|
|||||||
module FieldValidator
|
module FieldValidator
|
||||||
class ImageName < Base
|
class ImageName < Base
|
||||||
|
|
||||||
MAX_NAME_LEN = 100
|
MAX_LEN = 100
|
||||||
NAME_REGEX = /\A[\w\-\.]{1,#{MAX_NAME_LEN}}\z/
|
|
||||||
|
|
||||||
def valid?
|
def valid?
|
||||||
!NAME_REGEX.match(@value).nil?
|
@value.length <= MAX_LEN
|
||||||
end
|
end
|
||||||
|
|
||||||
def message
|
def message
|
||||||
"Invalid value '#{@value}': it should contains symbols 'a-zA-Z0-9_-.' and length should be more then 1 and less or equals then #{MAX_NAME_LEN}"
|
"Invalid value '#{@value}': it should contains symbols 'a-zA-Z0-9_-.' and length should be more then 1 and less or equals then #{MAX_LEN}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
require_relative "base"
|
||||||
|
module Validators
|
||||||
|
module FieldValidator
|
||||||
|
class ImageUsername < Base
|
||||||
|
|
||||||
|
MAX_NAME_LEN = 100
|
||||||
|
NAME_REGEX = /\A[\w\-\.]{1,#{MAX_NAME_LEN}}\z/
|
||||||
|
|
||||||
|
def valid?
|
||||||
|
!NAME_REGEX.match(@value).nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def message
|
||||||
|
"Invalid value '#{@value}': it should contains symbols 'a-zA-Z0-9_-.' and length should be more then 1 and less or equals then #{MAX_NAME_LEN}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -71,7 +71,8 @@ module Devops
|
|||||||
"deploy_env" => @deploy_env.identifier,
|
"deploy_env" => @deploy_env.identifier,
|
||||||
"created_by" => options["created_by"],
|
"created_by" => options["created_by"],
|
||||||
"provider" => @deploy_env.provider,
|
"provider" => @deploy_env.provider,
|
||||||
"provider_account" => @deploy_env.provider_account
|
"provider_account" => @deploy_env.provider_account,
|
||||||
|
"private_ip" => options["private_ip"]
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -99,7 +99,8 @@ module Provider
|
|||||||
options = {
|
options = {
|
||||||
"InstanceType" => flavor,
|
"InstanceType" => flavor,
|
||||||
# "Placement.AvailabilityZone" => s.options[:availability_zone],
|
# "Placement.AvailabilityZone" => s.options[:availability_zone],
|
||||||
"KeyName" => self.ssh_key
|
"KeyName" => self.ssh_key,
|
||||||
|
"PrivateIpAddress" => s.private_ip
|
||||||
}
|
}
|
||||||
vpcId = nil
|
vpcId = nil
|
||||||
unless subnets.empty?
|
unless subnets.empty?
|
||||||
|
|||||||
@ -2,12 +2,13 @@ require 'db/mongo/models/image'
|
|||||||
|
|
||||||
RSpec.describe Devops::Model::Image, type: :model do
|
RSpec.describe Devops::Model::Image, type: :model do
|
||||||
let(:image) { build(:image) }
|
let(:image) { build(:image) }
|
||||||
let(:name_with_dash) { 'asd-asd' }
|
let(:string_with_dash) { 'asd-asd' }
|
||||||
let(:name_with_slash) { 'asd/asd' }
|
let(:string_with_slash) { 'asd/asd' }
|
||||||
|
let(:string_with_parenthesis) { 'centos 6.5 x86_64 (development instance)' }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(Provider::ProviderFactory).to receive(:providers).and_return(%w(openstack ec2 static'))
|
allow(Provider::ProviderFactory).to receive(:providers).and_return(%w(openstack ec2 static'))
|
||||||
allow_any_instance_of(Validators::Image::ImageInFilter).to receive(:available_images).and_return([{'id' => 'test_image'}, {'id' => name_with_dash}, {'id' => name_with_slash}])
|
allow_any_instance_of(Validators::Image::ImageInFilter).to receive(:available_images).and_return([{'id' => 'test_image'}, {'id' => string_with_dash}, {'id' => string_with_slash}])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is valid with correct attrs' do
|
it 'is valid with correct attrs' do
|
||||||
@ -21,16 +22,24 @@ RSpec.describe Devops::Model::Image, type: :model do
|
|||||||
include_examples 'field type validation', :bootstrap_template, :maybe_nil, :non_empty_string, :only_word_symbols, :field_validator
|
include_examples 'field type validation', :bootstrap_template, :maybe_nil, :non_empty_string, :only_word_symbols, :field_validator
|
||||||
|
|
||||||
it 'id should contain only letters, digits and dashes' do
|
it 'id should contain only letters, digits and dashes' do
|
||||||
expect(build(:image, id: name_with_dash)).to be_valid
|
expect(build(:image, id: string_with_dash)).to be_valid
|
||||||
expect(build(:image, id: name_with_slash)).not_to be_valid
|
expect(build(:image, id: string_with_slash)).not_to be_valid
|
||||||
|
expect(build(:image, id: string_with_parenthesis)).not_to be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
it "id should be included in image filters" do
|
it "id should be included in image filters" do
|
||||||
expect(build(:image, id: 'wrong')).not_to be_valid
|
expect(build(:image, id: 'wrong')).not_to be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'name should contain only letters, digits and dashes' do
|
it 'name may contain everything' do
|
||||||
expect(build(:image, name: name_with_slash)).not_to be_valid
|
expect(build(:image, name: string_with_dash)).to be_valid
|
||||||
|
expect(build(:image, name: string_with_slash)).to be_valid
|
||||||
|
expect(build(:image, name: string_with_parenthesis)).to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'name length should be less or equal than 100' do
|
||||||
|
expect(build(:image, name: 'a'*100)).to be_valid
|
||||||
|
expect(build(:image, name: 'a'*101)).not_to be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'bootstrap_template should be included in available bootstrap templates' do
|
it 'bootstrap_template should be included in available bootstrap templates' do
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user