diff --git a/devops-client/lib/devops-client/handler/server.rb b/devops-client/lib/devops-client/handler/server.rb index 9febf16..1d85e02 100644 --- a/devops-client/lib/devops-client/handler/server.rb +++ b/devops-client/lib/devops-client/handler/server.rb @@ -71,7 +71,7 @@ class Server < Handler :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? end diff --git a/devops-client/lib/devops-client/options/deploy_options.rb b/devops-client/lib/devops-client/options/deploy_options.rb index a23443d..abb657d 100644 --- a/devops-client/lib/devops-client/options/deploy_options.rb +++ b/devops-client/lib/devops-client/options/deploy_options.rb @@ -14,7 +14,7 @@ class DeployOptions < CommonOptions options do |parser, options| 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(",") end diff --git a/devops-client/lib/devops-client/options/helpers/devops_options_parser.rb b/devops-client/lib/devops-client/options/helpers/devops_options_parser.rb index c3fc63e..e0bd6ef 100644 --- a/devops-client/lib/devops-client/options/helpers/devops_options_parser.rb +++ b/devops-client/lib/devops-client/options/helpers/devops_options_parser.rb @@ -7,6 +7,7 @@ module Options class DevopsOptionsParser extend Forwardable attr_reader :parsed_options + attr_accessor :resource_name, :command_name # leave this duplication for a while TABLE_FORMAT = "table" @@ -46,8 +47,9 @@ module Options # it is used to set options values without later quiz. # Arguments description: # 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: + # :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: # :required (default) # :optional @@ -57,48 +59,59 @@ module Options # :option_key - key in result_options hash. Default - option_name.to_sym # :variable - default - option_name.upcase # :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 # # EXAMPLES: # 1) - # parser.recognize_option_value(:provider, 'stack') - # is equal to + # parser.resource_name = :stack + # parser.recognize_option_value(:provider) + # is equal to # opts.on("--provider provider", I18n.t("options.descriptions.stack.provider)) do |provider| # options[:provider] = provider # end # + # Also, you could pass resource name in attributes without need to use attr_accessor: + # parser.recognize_option_value(:provider, resource_name: :stack) + # # 2) - # parser.recognize_option_value(:provider, 'stack', type: :optional, default: 'openstack') - # is equal to + # parser.recognize_option_value(:provider, type: :optional, default: 'openstack') + # is equal to # options[:provider] = 'openstack' # opts.on("--provider [provider]", I18n.t("options.descriptions.stack.provider)) do |provider| # options[:provider] = provider # end # # 3) - # parser.recognize_option_value(:no_template, 'image', type: :switch, default: false, switch_value: true) - # is equal to + # parser.recognize_option_value(:no_template, type: :switch, default: false, switch_value: true) + # is equal to # options[:no_template] = false # opts.on("--no_template", I18n.t("options.descriptions.image.no_template)) do # options[:no_template] = true # end # # 4) - # parser.recognize_option_value(:parameters, 'stack') do |parameters| + # parser.recognize_option_value(:parameters) do |parameters| # options[:parameters] = JSON.parse(parameters) # end - # is equal to + # is equal to # opts.on("--parameters parameters", I18n.t("options.descriptions.stack.parameters)) do |parameters| # options[:parameters] = JSON.parse(parameters) # end - def recognize_option_value(option_name, resource_name, attrs={}, &block) - recognizer = OptionValueRecognizer.new(option_name, resource_name, attrs) + def recognize_option_value(option_name, attrs={}, &block) + 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) end 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 @parser.banner = "\n" + I18n.t("options.usage", :cmd => $0) + "\n\n" + I18n.t("options.commands") + ":\n" end diff --git a/devops-client/lib/devops-client/options/helpers/option_value_recognizer.rb b/devops-client/lib/devops-client/options/helpers/option_value_recognizer.rb index 6c1735a..e4ea362 100644 --- a/devops-client/lib/devops-client/options/helpers/option_value_recognizer.rb +++ b/devops-client/lib/devops-client/options/helpers/option_value_recognizer.rb @@ -3,14 +3,16 @@ # Description and examples of usage are in devops_option_parser.rb. class OptionValueRecognizer - def initialize(option_name, resource_name, attrs={}) - @option_name, @attrs = option_name, attrs + attr_reader :option_name, :i18n_scope, :attrs - set_type(option_name, resource_name) - set_option_key(option_name, resource_name) - set_description(option_name, resource_name) - set_variable(option_name, resource_name) - set_options_to_recognize(option_name, resource_name) + def initialize(option_name, i18n_scope, attrs={}) + @option_name, @i18n_scope, @attrs = option_name, i18n_scope, attrs + + set_type + set_option_key + set_description + set_variable + set_options_to_recognize end def recognize(parser, parsed_options, &block) @@ -29,7 +31,9 @@ class OptionValueRecognizer private - def set_type(option_name, resource_name) + + + def set_type @type = @attrs[:type] || :required raise "Illegal optional type: '#{@type}'" unless [:required, :optional, :switch].include?(@type) if @type == :switch && !@attrs.keys.include?(:switch_value) @@ -37,22 +41,15 @@ class OptionValueRecognizer end end - def set_option_key(option_name, resource_name) + def set_option_key @option_key = @attrs[:option_key] || option_name.to_sym end - def set_description(option_name, resource_name) - if @attrs[:description] - @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 + def set_description + @description = @attrs[:description] || I18n.t(i18n_scope) end - def set_variable(option_name, resource_name) + def set_variable variable = @attrs[:variable] || option_name.upcase @variable = case @type @@ -65,7 +62,7 @@ class OptionValueRecognizer end end - def set_options_to_recognize(option_name, resource_name) + def set_options_to_recognize full = "--#{@option_name}#{@variable}" @options_to_recognize = [full] @options_to_recognize.unshift(@attrs[:short]) if @attrs[:short] diff --git a/devops-client/lib/devops-client/options/image_options.rb b/devops-client/lib/devops-client/options/image_options.rb index df737ad..587488b 100644 --- a/devops-client/lib/devops-client/options/image_options.rb +++ b/devops-client/lib/devops-client/options/image_options.rb @@ -17,12 +17,13 @@ class ImageOptions < CommonOptions def create_options self.options do |parser, options| parser.banner << self.create_banner + parser.resource_name = :image - parser.recognize_option_value(:provider, 'image') - parser.recognize_option_value(:image_id, 'image') - parser.recognize_option_value(:ssh_username, 'image') - parser.recognize_option_value(:bootstrap_template, 'image') - parser.recognize_option_value(:no_bootstrap_template, 'image', type: :switch, switch_value: true, default: false) + parser.recognize_option_value(:provider) + parser.recognize_option_value(:image_id) + parser.recognize_option_value(:ssh_username) + parser.recognize_option_value(:bootstrap_template) + parser.recognize_option_value(:no_bootstrap_template, type: :switch, switch_value: true, default: false) end end diff --git a/devops-client/lib/devops-client/options/project_options.rb b/devops-client/lib/devops-client/options/project_options.rb index 3bbd72e..64727e0 100644 --- a/devops-client/lib/devops-client/options/project_options.rb +++ b/devops-client/lib/devops-client/options/project_options.rb @@ -29,31 +29,32 @@ class ProjectOptions < CommonOptions def create_options self.options do |parser, options| 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(",") 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) options[:file] = file 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(",") 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(",")) end - parser.recognize_option_value(:deploy_env, 'project', option_key: :identifier) - parser.recognize_option_value(:flavor, 'project') - parser.recognize_option_value(:image, 'project') - parser.recognize_option_value(:run_list, 'project') - parser.recognize_option_value(:provider, 'project') - parser.recognize_option_value(:no_expires, 'project', type: :switch, switch_value: true, default: false) - parser.recognize_option_value(:expires, 'project') + parser.recognize_option_value(:deploy_env, option_key: :identifier) + parser.recognize_option_value(:flavor) + parser.recognize_option_value(:image) + parser.recognize_option_value(:run_list) + parser.recognize_option_value(:provider) + parser.recognize_option_value(:no_expires, type: :switch, switch_value: true, default: false) + parser.recognize_option_value(:expires) # TODO: @@ -72,7 +73,7 @@ class ProjectOptions < CommonOptions self.options do |parser, options| 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 @@ -80,7 +81,7 @@ class ProjectOptions < CommonOptions self.options do |parser, options| 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 @@ -88,7 +89,7 @@ class ProjectOptions < CommonOptions options do |parser, options| 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(",") end end @@ -96,7 +97,7 @@ class ProjectOptions < CommonOptions def delete_servers_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 diff --git a/devops-client/lib/devops-client/options/script_options.rb b/devops-client/lib/devops-client/options/script_options.rb index caab4a0..42ffe54 100644 --- a/devops-client/lib/devops-client/options/script_options.rb +++ b/devops-client/lib/devops-client/options/script_options.rb @@ -19,7 +19,7 @@ class ScriptOptions < CommonOptions options do |parser, options| 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(",") end end diff --git a/devops-client/lib/devops-client/options/server_options.rb b/devops-client/lib/devops-client/options/server_options.rb index 71461d0..7a44bc0 100644 --- a/devops-client/lib/devops-client/options/server_options.rb +++ b/devops-client/lib/devops-client/options/server_options.rb @@ -24,22 +24,21 @@ class ServerOptions < CommonOptions def delete_options options do |parser, options| 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, default: 'node', switch_value: 'instance', - option_key: :key, - i18n_scope: 'delete' + option_key: :key ) - parser.recognize_option_value(:no_ask, 'server', + parser.recognize_option_value(:no_ask, type: :switch, default: false, - switch_value: true, - i18n_scope: 'delete' + switch_value: true ) - end end @@ -47,12 +46,13 @@ class ServerOptions < CommonOptions options do |parser, options| parser.banner << self.delete_banner - parser.recognize_option_value(:instance, 'server', + parser.recognize_option_value(:instance, + resource_name: :server, + command_name: :pause, type: :switch, default: 'node', switch_value: 'instance', - option_key: :key, - i18n_scope: 'pause' + option_key: :key ) end end @@ -61,12 +61,13 @@ class ServerOptions < CommonOptions options do |parser, options| parser.banner << self.delete_banner - parser.recognize_option_value(:instance, 'server', + parser.recognize_option_value(:instance, + resource_name: :server, + command_name: :unpause, type: :switch, default: 'node', switch_value: 'instance', - option_key: :key, - i18n_scope: 'unpause' + option_key: :key ) end end @@ -75,12 +76,13 @@ class ServerOptions < CommonOptions options do |parser, options| parser.banner << self.delete_banner - parser.recognize_option_value(:instance, 'server', + parser.recognize_option_value(:instance, + resource_name: :server, + command_name: :reserve, type: :switch, default: 'node', switch_value: 'instance', - option_key: :key, - i18n_scope: 'reserve' + option_key: :key ) end end @@ -89,12 +91,13 @@ class ServerOptions < CommonOptions options do |parser, options| parser.banner << self.delete_banner - parser.recognize_option_value(:instance, 'server', + parser.recognize_option_value(:instance, + resource_name: :server, + command_name: :unreserve, type: :switch, default: 'node', switch_value: 'instance', - option_key: :key, - i18n_scope: 'unreserve' + option_key: :key ) end end @@ -102,26 +105,29 @@ class ServerOptions < CommonOptions def create_options options do |parser, options| 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, switch_value: true, option_key: :without_bootstrap, i18n_scope: 'create' ) - parser.recognize_option_value(:name, 'server', short: '-N', i18n_scope: 'create') - parser.recognize_option_value(:force, 'server', short: '-f', i18n_scope: 'create') - parser.recognize_option_value(:key, 'server', i18n_scope: 'create') + parser.recognize_option_value(:name, short: '-N') + parser.recognize_option_value(:force, short: '-f') + parser.recognize_option_value(:key) - parser.recognize_option_value(:groups, 'server', + parser.recognize_option_value(:groups, short: '-G', - variable: 'GROUP_1,GROUP_2...', - i18n_scope: 'create' + variable: 'GROUP_1,GROUP_2...' ) do |groups| options[:groups] = groups.split(",") end + parser.recognize_option_value(:private_ip, 'server', short: '-N', i18n_scope: 'create') + # it was disabled somewhy # parser.on('--public-ip', "Associate public IP with server") do # options[:public_ip] = true @@ -132,10 +138,12 @@ class ServerOptions < CommonOptions def bootstrap_options options do |parser, options| 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(:bootstrap_template, 'server', i18n_scope: 'bootstrap') - parser.recognize_option_value(:run_list, 'server', i18n_scope: 'bootstrap') do |list| + parser.recognize_option_value(:name, short: '-N') + parser.recognize_option_value(:bootstrap_template) + parser.recognize_option_value(:run_list) do |list| options[:run_list] = list.split(",") end end @@ -145,7 +153,7 @@ class ServerOptions < CommonOptions options do |parser, options| 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 diff --git a/devops-client/lib/devops-client/options/stack_options.rb b/devops-client/lib/devops-client/options/stack_options.rb index c33c25a..325e629 100644 --- a/devops-client/lib/devops-client/options/stack_options.rb +++ b/devops-client/lib/devops-client/options/stack_options.rb @@ -21,16 +21,16 @@ class StackOptions < CommonOptions def create_options self.options do |parser, options| parser.banner << self.create_banner + parser.resource_name = :stack - parser.recognize_option_value(:provider, 'stack') - parser.recognize_option_value(:id, 'stack') - parser.recognize_option_value(:project, 'stack') - parser.recognize_option_value(:deploy_env, 'stack') - parser.recognize_option_value(:stack_template, 'stack') - parser.recognize_option_value(:parameters_file, 'stack') - parser.recognize_option_value(:run_list, 'stack') - parser.recognize_option_value(:without_bootstrap, 'stack', type: :switch, switch_value: true) - + parser.recognize_option_value(:provider) + parser.recognize_option_value(:id) + parser.recognize_option_value(:project) + parser.recognize_option_value(:deploy_env) + parser.recognize_option_value(:stack_template) + parser.recognize_option_value(:parameters_file) + parser.recognize_option_value(:run_list) + parser.recognize_option_value(:without_bootstrap, type: :switch, switch_value: true) end end diff --git a/devops-client/lib/devops-client/options/stack_template_options.rb b/devops-client/lib/devops-client/options/stack_template_options.rb index 74b9d9e..3da56a9 100644 --- a/devops-client/lib/devops-client/options/stack_template_options.rb +++ b/devops-client/lib/devops-client/options/stack_template_options.rb @@ -17,10 +17,11 @@ class StackTemplateOptions < CommonOptions def create_options self.options do |parser, options| parser.banner << self.create_banner + parser.resource_name = :stack_template - parser.recognize_option_value(:provider, 'stack_template', default: nil) - parser.recognize_option_value(:id, 'stack_template') - parser.recognize_option_value(:template_file, 'stack_template') + parser.recognize_option_value(:provider, default: nil) + parser.recognize_option_value(:id) + parser.recognize_option_value(:template_file) end end diff --git a/devops-client/lib/devops-client/options/user_options.rb b/devops-client/lib/devops-client/options/user_options.rb index e224431..f6da6e0 100644 --- a/devops-client/lib/devops-client/options/user_options.rb +++ b/devops-client/lib/devops-client/options/user_options.rb @@ -18,7 +18,7 @@ class UserOptions < CommonOptions self.options do |parser, options| parser.banner << self.create_banner - parser.recognize_option_value(:new_password, 'user') + parser.recognize_option_value(:new_password, resource_name: :user) end end diff --git a/devops-client/locales/en.yml b/devops-client/locales/en.yml index 34c0f01..119e419 100644 --- a/devops-client/locales/en.yml +++ b/devops-client/locales/en.yml @@ -349,11 +349,12 @@ en: unreserve: instance: Unreserve server by instance id create: - without-bootstrap: 'Run server without bootsraping phase' + without_bootstrap: 'Run server without bootsraping phase' name: Set node name groups: The security groups for this server force: Cancel rollback operation on error key: User another key for server + private_ip: Private ip for this server bootstrap: name: Set chef name bootstrap_template: Bootstrap template @@ -366,7 +367,9 @@ en: deploy_env: Deploy env project: Stack project 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: provider: Stack template provider id: Stack template id diff --git a/devops-service/app/api2/routes/server.rb b/devops-service/app/api2/routes/server.rb index b00d983..69bd54e 100644 --- a/devops-service/app/api2/routes/server.rb +++ b/devops-service/app/api2/routes/server.rb @@ -196,6 +196,7 @@ module Devops # "force": null, -> do not delete server on error # "groups": [], -> specify special security groups, 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 diff --git a/devops-service/db/mongo/models/image.rb b/devops-service/db/mongo/models/image.rb index 2eb249a..8ccfc59 100644 --- a/devops-service/db/mongo/models/image.rb +++ b/devops-service/db/mongo/models/image.rb @@ -23,13 +23,13 @@ module Devops set_field_validators :id, [::Validators::FieldValidator::NotNil, ::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::NotEmpty, - ::Validators::FieldValidator::ImageName, + ::Validators::FieldValidator::ImageId, ::Validators::Image::ImageInFilter] set_field_validators :remote_user, [::Validators::FieldValidator::NotNil, ::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::NotEmpty, - ::Validators::FieldValidator::ImageName] + ::Validators::FieldValidator::ImageUsername] set_field_validators :name, [::Validators::FieldValidator::NotNil, ::Validators::FieldValidator::FieldType::String, diff --git a/devops-service/db/validators/field_validators/image_id.rb b/devops-service/db/validators/field_validators/image_id.rb new file mode 100644 index 0000000..926a2f6 --- /dev/null +++ b/devops-service/db/validators/field_validators/image_id.rb @@ -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 diff --git a/devops-service/db/validators/field_validators/image_name.rb b/devops-service/db/validators/field_validators/image_name.rb index e886a53..c108246 100644 --- a/devops-service/db/validators/field_validators/image_name.rb +++ b/devops-service/db/validators/field_validators/image_name.rb @@ -3,15 +3,14 @@ module Validators module FieldValidator class ImageName < Base - MAX_NAME_LEN = 100 - NAME_REGEX = /\A[\w\-\.]{1,#{MAX_NAME_LEN}}\z/ + MAX_LEN = 100 def valid? - !NAME_REGEX.match(@value).nil? + @value.length <= MAX_LEN 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}" + "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 diff --git a/devops-service/db/validators/field_validators/image_username.rb b/devops-service/db/validators/field_validators/image_username.rb new file mode 100644 index 0000000..334011d --- /dev/null +++ b/devops-service/db/validators/field_validators/image_username.rb @@ -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 diff --git a/devops-service/lib/executors/server_executor.rb b/devops-service/lib/executors/server_executor.rb index 06d8425..a8aebc6 100644 --- a/devops-service/lib/executors/server_executor.rb +++ b/devops-service/lib/executors/server_executor.rb @@ -71,7 +71,8 @@ module Devops "deploy_env" => @deploy_env.identifier, "created_by" => options["created_by"], "provider" => @deploy_env.provider, - "provider_account" => @deploy_env.provider_account + "provider_account" => @deploy_env.provider_account, + "private_ip" => options["private_ip"] }) end diff --git a/devops-service/providers/ec2.rb b/devops-service/providers/ec2.rb index 84860a6..be008f4 100644 --- a/devops-service/providers/ec2.rb +++ b/devops-service/providers/ec2.rb @@ -99,7 +99,8 @@ module Provider options = { "InstanceType" => flavor, # "Placement.AvailabilityZone" => s.options[:availability_zone], - "KeyName" => self.ssh_key + "KeyName" => self.ssh_key, + "PrivateIpAddress" => s.private_ip } vpcId = nil unless subnets.empty? diff --git a/devops-service/spec/models/image_spec.rb b/devops-service/spec/models/image_spec.rb index 9d78424..39e630d 100644 --- a/devops-service/spec/models/image_spec.rb +++ b/devops-service/spec/models/image_spec.rb @@ -2,12 +2,13 @@ require 'db/mongo/models/image' RSpec.describe Devops::Model::Image, type: :model do let(:image) { build(:image) } - let(:name_with_dash) { 'asd-asd' } - let(:name_with_slash) { 'asd/asd' } + let(:string_with_dash) { 'asd-asd' } + let(:string_with_slash) { 'asd/asd' } + let(:string_with_parenthesis) { 'centos 6.5 x86_64 (development instance)' } before do 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 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 it 'id should contain only letters, digits and dashes' do - expect(build(:image, id: name_with_dash)).to be_valid - expect(build(:image, id: name_with_slash)).not_to be_valid + expect(build(:image, id: string_with_dash)).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 it "id should be included in image filters" do expect(build(:image, id: 'wrong')).not_to be_valid end - it 'name should contain only letters, digits and dashes' do - expect(build(:image, name: name_with_slash)).not_to be_valid + it 'name may contain everything' do + 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 it 'bootstrap_template should be included in available bootstrap templates' do