Merge branch 'qa' of /home/git/repositories/cloudtechlab/devops-service into release
This commit is contained in:
commit
3c8274cdab
@ -1,7 +1,6 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems'
|
||||
require 'bundler'
|
||||
Bundler.require(:default, :development)
|
||||
require 'devops-client'
|
||||
|
||||
DevopsClient.run
|
||||
|
||||
@ -94,19 +94,36 @@ module Devops
|
||||
end
|
||||
end
|
||||
|
||||
def add_or_update_deploy_env id, deploy_env
|
||||
def update_deploy_env_field id, deploy_env, field
|
||||
project = Devops::Db.connector.project(id)
|
||||
env = parser.add_or_update_deploy_env
|
||||
db_env = project.deploy_env(deploy_env)
|
||||
value = parser.update_deploy_env_field
|
||||
if db_env.respond_to?(field + "=")
|
||||
if field == "identifier"
|
||||
db_env.rename id, value
|
||||
"Environment '#{deploy_env}' has been renamed to '#{value}'"
|
||||
else
|
||||
db_env.update_field(id, field, value)
|
||||
"Environment's field '#{field}' has been updated"
|
||||
end
|
||||
else
|
||||
raise RecordNotFound.new("Field '#{field}' does not exist")
|
||||
end
|
||||
end
|
||||
|
||||
def update_deploy_env id, deploy_env
|
||||
project = Devops::Db.connector.project(id)
|
||||
db_env = project.deploy_env(deploy_env)
|
||||
env = parser.update_deploy_env
|
||||
env.identifier = deploy_env if env.identifier.nil?
|
||||
begin
|
||||
db_env = project.deploy_env(deploy_env)
|
||||
unless env.identifier == deploy_env
|
||||
servers = Devops::Db.connector.servers_by_project_and_deploy_env(id, deploy_env)
|
||||
raise InvalidRecord.new("Can not update environment '#{deploy_env}', there are #{servers.size} servers on it") unless servers.empty?
|
||||
raise InvalidRecord.new("Environment '#{deploy_env}' can't be updated: it has #{servers.size} running servers.") unless servers.empty?
|
||||
end
|
||||
begin
|
||||
project.deploy_env(env.identifier)
|
||||
raise InvalidRecord.new("Can not change environment '#{deploy_env}' to '#{env.identifier}', environment '#{env.identifier}' already exist") unless deploy_env == env.identifier
|
||||
raise InvalidRecord.new("Environment '#{deploy_env}' can't be renamed to '#{env.identifier}', environment '#{env.identifier}' already exists") unless deploy_env == env.identifier
|
||||
rescue RecordNotFound => e
|
||||
end
|
||||
env.validate!
|
||||
@ -168,13 +185,15 @@ module Devops
|
||||
|
||||
def delete_project id
|
||||
deploy_env = parser.delete
|
||||
servers = Devops::Db.connector.servers id
|
||||
raise DependencyError.new "Deleting #{id} is forbidden: Project has servers" if !servers.empty?
|
||||
project = Devops::Db.connector.project(id)
|
||||
info = if deploy_env.nil?
|
||||
if deploy_env.nil?
|
||||
servers = Devops::Db.connector.servers id
|
||||
raise DependencyError.new "Deleting project #{id} is forbidden: Project has servers" unless servers.empty?
|
||||
project.delete
|
||||
"Project '#{id}' is deleted"
|
||||
else
|
||||
servers = Devops::Db.connector.servers id, deploy_env
|
||||
raise DependencyError.new "Deleting deploy_env #{deploy_env} is forbidden: Project has servers" unless servers.empty?
|
||||
project.delete_deploy_env(deploy_env)
|
||||
"Project '#{id}'. Deploy environment '#{deploy_env}' has been deleted"
|
||||
end
|
||||
@ -279,49 +298,6 @@ module Devops
|
||||
return [uri]
|
||||
end
|
||||
|
||||
=begin
|
||||
def create_roles project_id, envs
|
||||
all_roles = KnifeFactory.instance.roles
|
||||
return " Can't get roles list" if all_roles.nil?
|
||||
roles = {:new => [], :error => [], :exist => []}
|
||||
envs.each do |e|
|
||||
role_name = KnifeCommands.role_name(project_id, e.identifier)
|
||||
begin
|
||||
if all_roles.include? role_name
|
||||
roles[:exist].push role_name
|
||||
else
|
||||
KnifeCommands.create_role role_name, project_id, e.identifier
|
||||
roles[:new].push role_name
|
||||
DevopsLogger.logger.info "Role '#{role_name}' created"
|
||||
end
|
||||
rescue => er
|
||||
roles[:error].push role_name
|
||||
DevopsLogger.logger.error "Role '#{role_name}' can not be created: #{er.message}"
|
||||
end
|
||||
end
|
||||
roles
|
||||
end
|
||||
|
||||
def create_new_roles old_project, new_project
|
||||
old_project.deploy_envs.each do |e|
|
||||
new_project.deploy_envs.delete_if {|env| e.identifier == env.identifier}
|
||||
end
|
||||
create_roles new_project.id, new_project.deploy_envs
|
||||
end
|
||||
|
||||
def create_roles_response roles
|
||||
if roles.is_a?(String)
|
||||
roles
|
||||
else
|
||||
info = ""
|
||||
info += " Project roles '#{roles[:new].join("', '")}' have been automaticaly created" unless roles[:new].empty?
|
||||
info += " Project roles '#{roles[:exist].join("', '")}' weren't created because they exist" unless roles[:exist].empty?
|
||||
info += " Project roles '#{roles[:error].join("', '")}' weren't created because of internal error" unless roles[:error].empty?
|
||||
info
|
||||
end
|
||||
end
|
||||
=end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -186,6 +186,13 @@ module Devops
|
||||
return s, rl || d.run_list, t
|
||||
end
|
||||
|
||||
def unbootstrap_server id
|
||||
s = get_server_by_key(id, parser.instance_key)
|
||||
### Authorization
|
||||
Devops::Db.connector.check_project_auth s.project, s.deploy_env, parser.current_user
|
||||
Devops::Executor::ServerExecutor.new(s, "").unbootstrap
|
||||
end
|
||||
|
||||
def add_server
|
||||
body = parser.add_server
|
||||
project = body["project"]
|
||||
|
||||
@ -35,22 +35,29 @@ module Devops
|
||||
if envs_with_this_template.empty?
|
||||
Devops::Db.connector.stack_template_delete id
|
||||
else
|
||||
raise ConflictException.new("Stack template '#{id}' is already in use in #{envs_with_this_template.join(', ')}")
|
||||
raise ConflictException.new("Stack template '#{id}' is already in use in #{envs_with_this_template.map{|project, envs| "#{project}: #{envs.join(', ')}"}.join('; ')}", {projects: envs_with_this_template})
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# returns:
|
||||
# {
|
||||
# "project" => ["deploy_env"]
|
||||
# }
|
||||
def envs_using_stack_template(id)
|
||||
projects = Devops::Db.connector.projects_and_deploy_envs_by_field('stack_template', id)
|
||||
envs_with_this_template = []
|
||||
res = {}
|
||||
|
||||
projects.each do |project|
|
||||
array = []
|
||||
res[project.id] = array
|
||||
project.deploy_envs.each do |env|
|
||||
envs_with_this_template << "#{project.id}-#{env.identifier}"
|
||||
array << env.identifier
|
||||
end
|
||||
end
|
||||
envs_with_this_template
|
||||
res
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -6,7 +6,8 @@ module Devops
|
||||
class ImageParser < RequestParser
|
||||
|
||||
def images
|
||||
provider = @params[:provider]
|
||||
provider = @params["provider"]
|
||||
puts "Provider: #{provider}"
|
||||
check_provider(provider) if provider
|
||||
provider
|
||||
end
|
||||
|
||||
@ -7,7 +7,7 @@ module Devops
|
||||
|
||||
def create
|
||||
key = create_object_from_json_body
|
||||
fname = check_filename(key["file_name"], "Parameter 'file_name' must be a not empty string")
|
||||
fname = check_filename(key["file_name"], "Parameter 'file_name' should be a not empty string")
|
||||
kname = check_string(key["key_name"], "Parameter 'key_name' should be a not empty string")
|
||||
content = check_string(key["content"], "Parameter 'content' should be a not empty string")
|
||||
key
|
||||
|
||||
@ -50,10 +50,16 @@ module Devops
|
||||
Devops::Model::DeployEnvFactory.create(body)
|
||||
end
|
||||
|
||||
def add_or_update_deploy_env
|
||||
def update_deploy_env_field
|
||||
body = create_object_from_json_body
|
||||
rl = check_array(body["run_list"], "Parameter 'run_list' should be an array of string", String, false, true)
|
||||
Validators::Helpers::RunList.new(rl).validate!
|
||||
raise InvalidRecord.new("'value' key not found") if body["value"].nil?
|
||||
body["value"]
|
||||
end
|
||||
|
||||
def update_deploy_env
|
||||
body = create_object_from_json_body
|
||||
# rl = check_array(body["run_list"], "Parameter 'run_list' should be an array of string", String, false, true)
|
||||
# Validators::Helpers::RunList.new(rl).validate!
|
||||
Devops::Model::DeployEnvFactory.create(body)
|
||||
end
|
||||
|
||||
|
||||
@ -16,18 +16,16 @@ module Devops
|
||||
def user_privileges
|
||||
data = create_object_from_json_body
|
||||
cmd = check_string(data["cmd"], "Parameter 'cmd' should be a not empty string", true)
|
||||
privileges = check_string(data["privileges"], "Parameter 'privileges' should be a not empty string", true)
|
||||
privileges = check_string(data["privileges"], "Parameter 'privileges' should be a string", true, true)
|
||||
return cmd, privileges
|
||||
end
|
||||
|
||||
def change_password
|
||||
raise InvalidPrivileges.new("Access denied for '#{current_user}'") if user == Devops::Model::User::ROOT_USER_NAME and current_user != Devops::Model::User::ROOT_USER_NAME
|
||||
body = create_object_from_json_body
|
||||
check_string(body["password"], "Parameter 'password' must be a not empty string")
|
||||
end
|
||||
|
||||
def change_email
|
||||
raise InvalidPrivileges.new("Access denied for '#{current_user}'") if user == Devops::Model::User::ROOT_USER_NAME and current_user != Devops::Model::User::ROOT_USER_NAME
|
||||
body = create_object_from_json_body
|
||||
check_string(body["email"], "Parameter 'email' must be a not empty string")
|
||||
end
|
||||
|
||||
@ -22,7 +22,7 @@ module Devops
|
||||
# ]
|
||||
app.get_with_headers "/keys", :headers => [:accept] do
|
||||
check_privileges("key", "r")
|
||||
json Devops::API2_0::Handler::Key.new(request).keys.map(&:to_hash)
|
||||
json Devops::API2_0::Handler::Key.new(request).keys.map{|k| h = k.to_hash; h.delete("path"); h}
|
||||
end
|
||||
|
||||
# Create ssh key on devops server
|
||||
|
||||
@ -36,7 +36,8 @@ module Devops
|
||||
# ]
|
||||
app.get_with_headers "/projects", :headers => [:accept] do
|
||||
check_privileges("project", "r")
|
||||
json Devops::API2_0::Handler::Project.new(request).projects.map(&:to_hash_list)
|
||||
projects = Devops::API2_0::Handler::Project.new(request).projects
|
||||
json projects.map(&:to_hash)
|
||||
end
|
||||
|
||||
# Get project by id
|
||||
@ -217,6 +218,27 @@ module Devops
|
||||
# - method : POST
|
||||
# - headers :
|
||||
# - Accept: application/json
|
||||
# - body :
|
||||
# {
|
||||
# "identifier": "prod",
|
||||
# "provider": "openstack",
|
||||
# "flavor": "m1.small",
|
||||
# "image": "image id",
|
||||
# "subnets": [
|
||||
# "private"
|
||||
# ],
|
||||
# "groups": [
|
||||
# "default"
|
||||
# ],
|
||||
# "users": [
|
||||
# "user"
|
||||
# ],
|
||||
# "run_list": [ ],
|
||||
# "expires": null
|
||||
# }
|
||||
#
|
||||
# * *Returns* :
|
||||
# 200 - Added
|
||||
app.post_with_headers "/project/:project/deploy_env", :headers => [:accept, :content_type] do |project|
|
||||
check_privileges("project", "w")
|
||||
res, env = Devops::API2_0::Handler::Project.new(request).add_deploy_env(project)
|
||||
@ -235,7 +257,7 @@ module Devops
|
||||
json Devops::API2_0::Handler::Project.new(request).project_deploy_env(project, env)
|
||||
}
|
||||
|
||||
# Add or update deploy_env
|
||||
# Update deploy_env, you can send few fields in the body
|
||||
#
|
||||
# * *Request*
|
||||
# - method : PUT
|
||||
@ -266,7 +288,7 @@ module Devops
|
||||
deploy_env_hash["PUT"] = lambda{|id, deploy_env|
|
||||
check_privileges("project", "w")
|
||||
begin
|
||||
res = Devops::API2_0::Handler::Project.new(request).add_or_update_deploy_env(id, deploy_env)
|
||||
res = Devops::API2_0::Handler::Project.new(request).update_deploy_env(id, deploy_env)
|
||||
create_response(res, nil, 200)
|
||||
rescue InvalidRecord => e
|
||||
halt_response(e.message)
|
||||
@ -293,6 +315,12 @@ module Devops
|
||||
}
|
||||
app.multi_routes "/project/:id/deploy_envs/:deploy_env", {}, deploy_env_hash
|
||||
|
||||
app.put_with_headers "/project/:id/deploy_env/:deploy_env/:field", :headers => [:accept, :content_type] do |project_id, deploy_env, field|
|
||||
check_privileges("project", "w")
|
||||
res = Devops::API2_0::Handler::Project.new(request).update_deploy_env_field(project_id, deploy_env, field)
|
||||
create_response(res, nil, 200)
|
||||
end
|
||||
|
||||
# Create project
|
||||
#
|
||||
# * *Request*
|
||||
|
||||
@ -279,6 +279,25 @@ module Devops
|
||||
end
|
||||
end
|
||||
|
||||
# Unbootstrap devops server
|
||||
#
|
||||
# * *Request*
|
||||
# - method : POST
|
||||
# - headers :
|
||||
# - Accept: application/json
|
||||
# - Content-Type: application/json
|
||||
# - body :
|
||||
# {
|
||||
# "key": "instance", -> search server by instance_id rather then chef_node_name
|
||||
# }
|
||||
#
|
||||
# * *Returns* : 200
|
||||
app.post_with_headers "/server/:id/unbootstrap", :headers => [:accept, :content_type] do |id|
|
||||
check_privileges("server", "w")
|
||||
info = Devops::API2_0::Handler::Server.new(request).unbootstrap_server(id)
|
||||
create_response("Unbootstrap", info)
|
||||
end
|
||||
|
||||
# Add external server to devops
|
||||
#
|
||||
# * *Request*
|
||||
|
||||
@ -113,7 +113,9 @@ module Devops
|
||||
# * *Returns* :
|
||||
# 200 - Updated
|
||||
app.put_with_headers %r{\A/user/#{DevopsConfig::OBJECT_NAME}/email\z}, :headers => [:accept, :content_type] do |user|
|
||||
check_privileges("user", "w") unless request.env['REMOTE_USER'] == user
|
||||
current_user = request.env['REMOTE_USER']
|
||||
check_privileges("user", "w") unless current_user == user
|
||||
raise InvalidPrivileges.new("Access denied for '#{current_user}'") if user == Devops::Model::User::ROOT_USER_NAME and current_user != Devops::Model::User::ROOT_USER_NAME
|
||||
Devops::API2_0::Handler::User.new(request).change_email(user)
|
||||
create_response("Updated")
|
||||
end
|
||||
@ -133,7 +135,9 @@ module Devops
|
||||
# * *Returns* :
|
||||
# 200 - Updated
|
||||
app.put_with_headers %r{\A/user/#{DevopsConfig::OBJECT_NAME}/password\z}, :headers => [:accept, :content_type] do |user|
|
||||
check_privileges("user", "w") unless request.env['REMOTE_USER'] == user
|
||||
current_user = request.env['REMOTE_USER']
|
||||
check_privileges("user", "w") unless current_user == user
|
||||
raise InvalidPrivileges.new("Access denied for '#{current_user}'") if user == Devops::Model::User::ROOT_USER_NAME and current_user != Devops::Model::User::ROOT_USER_NAME
|
||||
Devops::API2_0::Handler::User.new(request).change_password(user)
|
||||
create_response("Updated")
|
||||
end
|
||||
|
||||
@ -10,6 +10,7 @@ require "exceptions/dependency_error"
|
||||
require "exceptions/conflict_exception"
|
||||
require "exceptions/parser_error"
|
||||
require "exceptions/validation_error"
|
||||
require "exceptions/knife_config_error"
|
||||
require 'core/devops-logger'
|
||||
|
||||
require_relative "../helpers/version_2"
|
||||
@ -58,8 +59,12 @@ module Devops
|
||||
# set current logger and call handlers
|
||||
def call env
|
||||
DevopsLogger.logger = @@logger
|
||||
begin
|
||||
res = super(env)
|
||||
@@access_logger.info(env["REQUEST_METHOD"] + " " + env["REQUEST_URI"] + " - from #{env["HTTP_USER_AGENT"]}")
|
||||
rescue DevopsError => e
|
||||
return [e.code, {}, e.message]
|
||||
end
|
||||
@@access_logger.info(env["REQUEST_METHOD"] + " " + env["REQUEST_URI"] + " - from #{env["HTTP_USER_AGENT"]} (#{env["REMOTE_USER"]}) / #{res.inspect}")
|
||||
res
|
||||
end
|
||||
|
||||
@ -75,6 +80,12 @@ module Devops
|
||||
halt_response(e.message, 400)
|
||||
end
|
||||
|
||||
error Devops::Exception::KnifeConfigError do
|
||||
e = env["sinatra.error"]
|
||||
logger.error e.message
|
||||
halt_response(e.message, 500)
|
||||
end
|
||||
|
||||
error RecordNotFound do
|
||||
e = env["sinatra.error"]
|
||||
logger.warn e.message
|
||||
@ -103,7 +114,7 @@ module Devops
|
||||
error ConflictException do
|
||||
e = env["sinatra.error"]
|
||||
logger.warn e.message
|
||||
halt_response(e.message, 409)
|
||||
create_response(e.message, e.object, 409)
|
||||
end
|
||||
|
||||
error InvalidPrivileges do
|
||||
|
||||
@ -2,7 +2,7 @@ require "socket"
|
||||
|
||||
class DevopsConfig
|
||||
|
||||
OBJECT_NAME = /[\w\-]+/
|
||||
OBJECT_NAME = /([\w\-]+)/
|
||||
|
||||
@@config = nil
|
||||
|
||||
|
||||
@ -20,7 +20,8 @@ module Connectors
|
||||
collection.insert(record.to_mongo_hash)
|
||||
record
|
||||
rescue Mongo::OperationFailure => e
|
||||
if e.message =~ /^11000/
|
||||
# exception's message doesn't always start from error code
|
||||
if e.message =~ /11000/
|
||||
resource_name = StringHelper.underscore_class(record.class)
|
||||
raise InvalidRecord.new("Duplicate key error: #{resource_name} with id '#{record.id}'")
|
||||
end
|
||||
|
||||
@ -35,6 +35,7 @@ module Connectors
|
||||
else
|
||||
query["archived"] = {"$exists" => false}
|
||||
end
|
||||
fields << '_id'
|
||||
list(query, fields: fields)
|
||||
end
|
||||
|
||||
@ -93,7 +94,7 @@ module Connectors
|
||||
|
||||
def check_project_auth(project_id, env, user_id)
|
||||
project = show(project_id)
|
||||
raise InvalidPrivileges.new("User '#{user_id}' unauthorized to work with project '#{project_id}'") unless project.check_authorization(user_id, env)
|
||||
raise InvalidPrivileges.new("User '#{user_id}' is unauthorized to work with project '#{project_id}' and environment '#{env}'") unless project.check_authorization(user_id, env)
|
||||
project
|
||||
end
|
||||
|
||||
@ -104,13 +105,17 @@ module Connectors
|
||||
list( {'deploy_envs' => {'$elemMatch' => q}}, {:fields => {'deploy_envs' => {'$elemMatch' => q}}} )
|
||||
end
|
||||
|
||||
def set_project_deploy_env_field(project_id, env, field, value)
|
||||
@collection.update({"_id" => project_id, "deploy_envs.identifier" => env}, {"$set" => {"deploy_envs.$.#{field}" => value}})
|
||||
def set_project_deploy_env_field(project_id, env, field_value_hash)
|
||||
set = {}
|
||||
field_value_hash.each do |field, value|
|
||||
set["deploy_envs.$.#{field}"] = value
|
||||
end
|
||||
@collection.update({"_id" => project_id, "deploy_envs.identifier" => env}, {"$set" => set})
|
||||
end
|
||||
|
||||
def set_project_env_run_list(project_id, env, run_list)
|
||||
Helpers::RunList.new(run_list).validate!
|
||||
set_project_deploy_env_field(project_id, env, "run_list", run_list)
|
||||
set_project_deploy_env_field(project_id, env, {"run_list" => run_list})
|
||||
end
|
||||
|
||||
def set_project_run_list(project_id, env, run_list)
|
||||
|
||||
@ -12,7 +12,8 @@ module Devops
|
||||
class CloudDeployEnv < DeployEnvBase
|
||||
|
||||
attr_accessor :flavor, :image, :subnets, :groups, :stack_template
|
||||
|
||||
=begin
|
||||
@Deprecated
|
||||
types :identifier => {:type => String, :empty => false},
|
||||
:image => {:type => String, :empty => false},
|
||||
:flavor => {:type => String, :empty => false},
|
||||
@ -23,6 +24,7 @@ module Devops
|
||||
:subnets => {:type => Array, :empty => true},
|
||||
:groups => {:type => Array, :empty => false},
|
||||
:stack_template => {:type => String, :empty => false, :nil => true}
|
||||
=end
|
||||
|
||||
set_validators ::Validators::DeployEnv::Flavor,
|
||||
::Validators::DeployEnv::Image,
|
||||
@ -31,6 +33,22 @@ module Devops
|
||||
::Validators::DeployEnv::Groups,
|
||||
::Validators::DeployEnv::StackTemplate
|
||||
# set_validators ::Validators::DeployEnv::CloudParameters
|
||||
set_field_validators :flavor, ::Validators::FieldValidator::Nil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::Flavor
|
||||
set_field_validators :image, ::Validators::FieldValidator::Nil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::Image
|
||||
set_field_validators :subnets, ::Validators::FieldValidator::Nil,
|
||||
::Validators::FieldValidator::FieldType::Array
|
||||
# ::Validators::FieldValidator::Subnets.new
|
||||
set_field_validators :groups, ::Validators::FieldValidator::Nil,
|
||||
::Validators::FieldValidator::FieldType::Array
|
||||
# ::Validators::FieldValidator::Groups.new
|
||||
set_field_validators :stack_template, ::Validators::FieldValidator::Nil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::NotEmpty,
|
||||
# ::Validators::FieldValidator::StackTemplate.new
|
||||
|
||||
def initialize d={}
|
||||
super(d)
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
require "db/mongo/models/mongo_model"
|
||||
require "providers/provider_factory"
|
||||
require "db/mongo/models/model_with_provider"
|
||||
require "db/validators/deploy_env/run_list"
|
||||
require "db/validators/deploy_env/expiration"
|
||||
require "db/validators/deploy_env/users"
|
||||
|
||||
module Devops
|
||||
module Model
|
||||
@ -17,6 +14,22 @@ module Devops
|
||||
::Validators::DeployEnv::Expiration,
|
||||
::Validators::DeployEnv::Users
|
||||
|
||||
set_field_validators :identifier, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::NotEmpty,
|
||||
::Validators::FieldValidator::Name
|
||||
|
||||
set_field_validators :run_list, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::Array,
|
||||
::Validators::FieldValidator::RunList
|
||||
|
||||
set_field_validators :users, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::Array
|
||||
|
||||
set_field_validators :expires, ::Validators::FieldValidator::Nil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::Expires
|
||||
|
||||
def initialize d={}
|
||||
self.identifier = d["identifier"]
|
||||
b = d["run_list"] || []
|
||||
@ -41,12 +54,40 @@ module Devops
|
||||
self.users = (self.users + users).uniq
|
||||
end
|
||||
|
||||
def rename project_id, new_name
|
||||
old_name = self.identifier
|
||||
self.identifier = new_name
|
||||
self.validate_identifier!
|
||||
begin
|
||||
project = Devops::Db.connector.project(project_id)
|
||||
project.deploy_env(self.identifier)
|
||||
raise InvalidRecord.new("Environment with identifier '#{new_name}' already exist in project '#{project_id}'")
|
||||
rescue RecordNotFound => e
|
||||
res = create_role(project_id)
|
||||
knife = knife_instance
|
||||
old_role_name = knife.role_name(project_id, old_name)
|
||||
self.run_list.delete("role[#{old_role_name}]")
|
||||
role = res[:new] || res[:exist]
|
||||
self.run_list << "role[#{role[0]}]" unless role.nil?
|
||||
Devops::Db.connector.set_project_deploy_env_field(project_id, old_name, {"identifier" => new_name, "run_list" => self.run_list})
|
||||
msg = "Project '#{project_id}': environment '#{old_name}' has been renamed to '#{new_name}'." + Project.create_roles_response(res)
|
||||
DevopsLogger.logger.info(msg)
|
||||
msg
|
||||
end
|
||||
end
|
||||
|
||||
def update_field project_id, field, value
|
||||
self.send(field + "=", value)
|
||||
self.send("validate_" + field + "!")
|
||||
Devops::Db.connector.set_project_deploy_env_field(project_id, self.identifier, {field => value})
|
||||
end
|
||||
|
||||
def build_error_message(message)
|
||||
"Deploy environment '#{self.identifier}'. " + message
|
||||
end
|
||||
|
||||
def create_role project_id
|
||||
knife = KnifeFactory.instance
|
||||
knife = knife_instance
|
||||
if knife.nil?
|
||||
DevopsLogger.logger.error "Can not get knife instance"
|
||||
return nil
|
||||
@ -56,25 +97,29 @@ module Devops
|
||||
if all_roles.nil?
|
||||
msg = "Can't get roles list from chef"
|
||||
DevopsLogger.logger.error msg
|
||||
return {error: msg}
|
||||
return {error: [msg]}
|
||||
end
|
||||
role_name = knife.role_name(project_id, self.identifier)
|
||||
begin
|
||||
if all_roles.include? role_name
|
||||
info[:exist] = role_name
|
||||
info[:exist] = [role_name]
|
||||
else
|
||||
knife.create_role role_name, project_id, self.identifier
|
||||
info[:new] = role_name
|
||||
info[:new] = [role_name]
|
||||
DevopsLogger.logger.info "Role '#{role_name}' created"
|
||||
end
|
||||
self.run_list << "role[#{role_name}]"
|
||||
rescue => er
|
||||
info[:error] = role_name
|
||||
info[:error] = [role_name]
|
||||
DevopsLogger.logger.error "Role '#{role_name}' can not be created: #{er.message}"
|
||||
end
|
||||
info
|
||||
end
|
||||
|
||||
def knife_instance
|
||||
KnifeFactory.instance
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -4,6 +4,8 @@ module Devops
|
||||
module Model
|
||||
class DeployEnvEc2 < CloudDeployEnv
|
||||
|
||||
=begin
|
||||
@Deprecated
|
||||
types :identifier => {:type => String, :empty => false},
|
||||
:image => {:type => String, :empty => false},
|
||||
:flavor => {:type => String, :empty => false},
|
||||
@ -14,6 +16,7 @@ module Devops
|
||||
:subnets => {:type => Array, :empty => true},
|
||||
:groups => {:type => Array, :empty => false},
|
||||
:stack_template => {:type => String, :empty => false, :nil => true}
|
||||
=end
|
||||
|
||||
=begin
|
||||
set_validators ::Validators::DeployEnv::RunList,
|
||||
|
||||
@ -1,20 +1,55 @@
|
||||
require "db/mongo/models/mongo_model"
|
||||
require "db/validators/image/bootstrap_template"
|
||||
require "db/validators/image/image_in_filter"
|
||||
require "db/mongo/models/model_with_provider"
|
||||
|
||||
module Devops
|
||||
module Model
|
||||
class Image < MongoModel
|
||||
include ModelWithProvider
|
||||
|
||||
attr_accessor :id, :provider, :remote_user, :name, :bootstrap_template
|
||||
attr_accessor :id, :remote_user, :name, :bootstrap_template
|
||||
=begin
|
||||
types :id => {:type => String, :empty => false},
|
||||
:provider => {:type => String, :empty => false},
|
||||
:remote_user => {:type => String, :empty => false},
|
||||
:name => {:type => String, :empty => true},
|
||||
:bootstrap_template => {:type => String, :empty => false, :nil => true}
|
||||
set_validators ::Validators::Image::ImageInFilter,
|
||||
=end
|
||||
|
||||
# set_validators ::Validators::Image::ImageInFilter,
|
||||
# ::Validators::Image::BootstrapTemplate
|
||||
|
||||
set_field_validators :id, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::NotEmpty,
|
||||
::Validators::FieldValidator::ImageName,
|
||||
::Validators::Image::ImageInFilter
|
||||
|
||||
set_field_validators :remote_user, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::NotEmpty,
|
||||
::Validators::FieldValidator::Name
|
||||
|
||||
set_field_validators :name, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::NotEmpty,
|
||||
::Validators::FieldValidator::ImageName
|
||||
|
||||
set_field_validators :bootstrap_template, ::Validators::FieldValidator::Nil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::NotEmpty,
|
||||
::Validators::FieldValidator::Name,
|
||||
::Validators::Image::BootstrapTemplate
|
||||
|
||||
def validate!
|
||||
validate_id!
|
||||
validate_provider!
|
||||
validate_remote_user!
|
||||
validate_name!
|
||||
validate_bootstrap_template!
|
||||
end
|
||||
|
||||
def initialize p={}
|
||||
self.id = p["id"]
|
||||
self.provider = p["provider"]
|
||||
|
||||
@ -6,6 +6,14 @@ module Devops
|
||||
|
||||
attr_accessor :provider
|
||||
|
||||
def ModelWithProvider.included(mod)
|
||||
|
||||
mod.set_field_validators :provider, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::NotEmpty,
|
||||
::Validators::FieldValidator::Provider
|
||||
end
|
||||
|
||||
def provider_instance
|
||||
@provider_instance ||= Provider::ProviderFactory.get(self.provider)
|
||||
end
|
||||
|
||||
@ -55,7 +55,7 @@ module Devops
|
||||
def validate!
|
||||
begin
|
||||
# TODO: we should validate type in request parser
|
||||
self.validate_fields_types
|
||||
# self.validate_fields_types
|
||||
self.class.validate_model(self)
|
||||
true
|
||||
rescue InvalidRecord => e
|
||||
@ -120,13 +120,17 @@ module Devops
|
||||
end
|
||||
|
||||
@validators = []
|
||||
# @field_validators = []
|
||||
class << self
|
||||
|
||||
attr_accessor :validators
|
||||
# attr_accessor :field_validators
|
||||
|
||||
def inherited(subclass)
|
||||
subclass.validators = []
|
||||
subclass.validators += self.validators
|
||||
# subclass.field_validators = []
|
||||
# subclass.field_validators += self.field_validators
|
||||
end
|
||||
|
||||
# all exceptions are handled in @validate! method
|
||||
@ -136,6 +140,16 @@ module Devops
|
||||
end
|
||||
end
|
||||
|
||||
# validate field value
|
||||
# if method validate! returns false, then stop validation without error
|
||||
def set_field_validators field, *validators
|
||||
define_method("validate_" + field.to_s + "!") do
|
||||
validators.each do |validator|
|
||||
break unless validator.new(self, send(field)).validate!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# private class methods
|
||||
private
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ module Devops
|
||||
def add_deploy_env deploy_env
|
||||
res = deploy_env.create_role(self.id)
|
||||
Devops::Db.connector.add_deploy_env_to_project self.id, deploy_env
|
||||
create_roles_response(res)
|
||||
Project.create_roles_response(res)
|
||||
end
|
||||
|
||||
def add_authorized_user user, env=nil
|
||||
@ -210,7 +210,7 @@ module Devops
|
||||
end
|
||||
end
|
||||
|
||||
def create_roles_response roles
|
||||
def self.create_roles_response roles
|
||||
if roles.is_a?(String)
|
||||
roles
|
||||
else
|
||||
|
||||
@ -17,6 +17,15 @@ module Devops
|
||||
:email => {:type => String, :empty => false},
|
||||
:password => {:type => String, :empty => true}
|
||||
|
||||
set_field_validators :id, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::String,
|
||||
::Validators::FieldValidator::Name
|
||||
set_field_validators :password, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::String
|
||||
set_field_validators :email, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::String
|
||||
set_field_validators :privileges, ::Validators::FieldValidator::NotNil,
|
||||
::Validators::FieldValidator::FieldType::Hash
|
||||
def initialize p={}
|
||||
self.id = p['username']
|
||||
self.email = p['email']
|
||||
@ -24,6 +33,13 @@ module Devops
|
||||
self.privileges = p["privileges"] || self.default_privileges
|
||||
end
|
||||
|
||||
def validate!
|
||||
validate_id!
|
||||
validate_password!
|
||||
validate_email!
|
||||
validate_privileges!
|
||||
end
|
||||
|
||||
def all_privileges
|
||||
privileges_with_value("rwx")
|
||||
end
|
||||
@ -33,6 +49,8 @@ module Devops
|
||||
end
|
||||
|
||||
def grant cmd, priv=''
|
||||
priv='' if priv.nil?
|
||||
cmd='' if cmd.nil?
|
||||
if !priv.empty? and PRIVILEGES_REGEX.match(priv).to_s.empty?
|
||||
raise InvalidCommand.new "Invalid privileges '#{priv}'. Available values are '#{PRIVILEGES.join("', '")}'"
|
||||
end
|
||||
@ -46,7 +64,7 @@ module Devops
|
||||
when ""
|
||||
self.privileges = self.default_privileges
|
||||
else
|
||||
raise InvalidCommand.new "Unsupported command #{cmd}" unless self.all_privileges.include?(cmd)
|
||||
raise InvalidCommand.new "Unsupported command '#{cmd}'" unless self.all_privileges.include?(cmd)
|
||||
self.privileges[cmd] = priv
|
||||
end
|
||||
end
|
||||
|
||||
@ -3,6 +3,8 @@ module Validators
|
||||
module DeployEnv; end
|
||||
module Key; end
|
||||
module Image; end
|
||||
|
||||
module FieldValidator; end
|
||||
end
|
||||
|
||||
require "db/validators/base"
|
||||
@ -10,7 +12,8 @@ require "db/validators/base"
|
||||
'db/validators/helpers/*.rb',
|
||||
'db/validators/deploy_env/*.rb',
|
||||
'db/validators/key/*.rb',
|
||||
'db/validators/image/*.rb'
|
||||
'db/validators/image/*.rb',
|
||||
'db/validators/field_validators/*.rb'
|
||||
].each do |files_regexp|
|
||||
Dir[files_regexp].each {|file| require file }
|
||||
end
|
||||
|
||||
25
devops-service/db/validators/field_validators/base.rb
Normal file
25
devops-service/db/validators/field_validators/base.rb
Normal file
@ -0,0 +1,25 @@
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class Base
|
||||
|
||||
def initialize model, value
|
||||
@model = model
|
||||
@value = value
|
||||
end
|
||||
|
||||
def validate!
|
||||
raise InvalidRecord.new(self.message) unless self.valid?
|
||||
true
|
||||
end
|
||||
|
||||
def valid?
|
||||
raise 'override me'
|
||||
end
|
||||
|
||||
def message
|
||||
raise 'override me'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
19
devops-service/db/validators/field_validators/expires.rb
Normal file
19
devops-service/db/validators/field_validators/expires.rb
Normal file
@ -0,0 +1,19 @@
|
||||
require_relative "base"
|
||||
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class Expires < Base
|
||||
|
||||
EXPIRES_REGEXP = /^[0-9]+[smhdw]$/
|
||||
|
||||
def valid?
|
||||
!@value.match(EXPIRES_REGEXP).nil?
|
||||
end
|
||||
|
||||
def message
|
||||
"Invalid value, it should contains symbols '0-9smhdw'"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
62
devops-service/db/validators/field_validators/field_type.rb
Normal file
62
devops-service/db/validators/field_validators/field_type.rb
Normal file
@ -0,0 +1,62 @@
|
||||
require_relative "base"
|
||||
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class FieldType < Base
|
||||
|
||||
def valid?
|
||||
@value.is_a?(type)
|
||||
#TODO: strip string
|
||||
#value.strip! if value.is_a?(String)
|
||||
end
|
||||
|
||||
def message
|
||||
"Invalid value, it should be a #{type_name}"
|
||||
end
|
||||
|
||||
class String < FieldType
|
||||
|
||||
def type
|
||||
::String
|
||||
end
|
||||
|
||||
def type_name
|
||||
"string"
|
||||
end
|
||||
end
|
||||
|
||||
class Array < FieldType
|
||||
|
||||
def type
|
||||
::Array
|
||||
end
|
||||
|
||||
def type_name
|
||||
"array"
|
||||
end
|
||||
|
||||
def message
|
||||
"Invalid value, it should be an #{type_name}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Hash < FieldType
|
||||
|
||||
def type
|
||||
::Hash
|
||||
end
|
||||
|
||||
def type_name
|
||||
"object"
|
||||
end
|
||||
|
||||
def message
|
||||
"Invalid value, it should be an #{type_name}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
18
devops-service/db/validators/field_validators/flavor.rb
Normal file
18
devops-service/db/validators/field_validators/flavor.rb
Normal file
@ -0,0 +1,18 @@
|
||||
require_relative "base"
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class Flavor < Base
|
||||
|
||||
def valid?
|
||||
@model.provider_instance.flavors.detect do |flavor|
|
||||
flavor['id'] == @value
|
||||
end
|
||||
end
|
||||
|
||||
def message
|
||||
"Invalid flavor '#{@value}'."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
22
devops-service/db/validators/field_validators/image.rb
Normal file
22
devops-service/db/validators/field_validators/image.rb
Normal file
@ -0,0 +1,22 @@
|
||||
require "commands/image"
|
||||
require_relative "base"
|
||||
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class Image < Base
|
||||
include ::ImageCommands
|
||||
|
||||
def valid?
|
||||
images = get_available_provider_images(::Devops::Db.connector, @model.provider)
|
||||
images.detect do |image|
|
||||
image["id"] == @value
|
||||
end
|
||||
end
|
||||
|
||||
def message
|
||||
"Invalid image '#{@value}'."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
18
devops-service/db/validators/field_validators/image_name.rb
Normal file
18
devops-service/db/validators/field_validators/image_name.rb
Normal file
@ -0,0 +1,18 @@
|
||||
require_relative "base"
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class ImageName < 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
|
||||
18
devops-service/db/validators/field_validators/name.rb
Normal file
18
devops-service/db/validators/field_validators/name.rb
Normal file
@ -0,0 +1,18 @@
|
||||
require_relative "base"
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class Name < Base
|
||||
|
||||
MAX_NAME_LEN = 200
|
||||
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
|
||||
14
devops-service/db/validators/field_validators/nil.rb
Normal file
14
devops-service/db/validators/field_validators/nil.rb
Normal file
@ -0,0 +1,14 @@
|
||||
require_relative "base"
|
||||
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class Nil < Base
|
||||
|
||||
def validate!
|
||||
!@value.nil?
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
18
devops-service/db/validators/field_validators/not_empty.rb
Normal file
18
devops-service/db/validators/field_validators/not_empty.rb
Normal file
@ -0,0 +1,18 @@
|
||||
require_relative "base"
|
||||
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class NotEmpty < Base
|
||||
|
||||
def valid?
|
||||
!@value.empty?
|
||||
end
|
||||
|
||||
def message
|
||||
"Value can not be empty"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
18
devops-service/db/validators/field_validators/not_nil.rb
Normal file
18
devops-service/db/validators/field_validators/not_nil.rb
Normal file
@ -0,0 +1,18 @@
|
||||
require_relative "base"
|
||||
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class NotNil < Base
|
||||
|
||||
def valid?
|
||||
!@value.nil?
|
||||
end
|
||||
|
||||
def message
|
||||
"Value can not be undefined"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
18
devops-service/db/validators/field_validators/provider.rb
Normal file
18
devops-service/db/validators/field_validators/provider.rb
Normal file
@ -0,0 +1,18 @@
|
||||
require_relative "base"
|
||||
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class Provider < Base
|
||||
|
||||
def valid?
|
||||
@providers = ::Provider::ProviderFactory.providers
|
||||
@providers.include?(@value)
|
||||
end
|
||||
|
||||
def message
|
||||
"Invalid value, available values: '#{@providers.join("', '")}'"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
13
devops-service/db/validators/field_validators/run_list.rb
Normal file
13
devops-service/db/validators/field_validators/run_list.rb
Normal file
@ -0,0 +1,13 @@
|
||||
require_relative "base"
|
||||
|
||||
module Validators
|
||||
module FieldValidator
|
||||
class RunList < Base
|
||||
|
||||
def validate!
|
||||
Validators::Helpers::RunList.new(@value).validate!
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,4 +1,11 @@
|
||||
class ConflictException < StandardError
|
||||
|
||||
attr_reader :object
|
||||
|
||||
def initialize msg, object=nil
|
||||
super(msg)
|
||||
@object = object
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
13
devops-service/exceptions/devops_error.rb
Normal file
13
devops-service/exceptions/devops_error.rb
Normal file
@ -0,0 +1,13 @@
|
||||
module Devops
|
||||
module Exception
|
||||
|
||||
class DevopsError < StandardError
|
||||
|
||||
def code
|
||||
500
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
9
devops-service/exceptions/knife_config_error.rb
Normal file
9
devops-service/exceptions/knife_config_error.rb
Normal file
@ -0,0 +1,9 @@
|
||||
require 'exceptions/devops_error'
|
||||
module Devops
|
||||
module Exception
|
||||
class KnifeConfigError < DevopsError
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -281,17 +281,27 @@ module Devops
|
||||
k = Devops::Db.connector.key(@server.key)
|
||||
cert_path = k.path
|
||||
i = 0
|
||||
res = delete_from_chef_server(@server.chef_node_name)
|
||||
begin
|
||||
r = `ssh -i #{cert_path} -q #{@server.remote_user}@#{@server.private_ip} rm -Rf /etc/chef`
|
||||
new_name = "/etc/chef.backup_#{Time.now.strftime("%d-%m-%Y_%H.%M.%S")}"
|
||||
# r = `ssh -i #{cert_path} -q #{@server.remote_user}@#{@server.private_ip} rm -Rf /etc/chef`
|
||||
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'\""
|
||||
DevopsLogger.logger.info("Trying to run command '#{cmd}'")
|
||||
r = `#{cmd}`.strip
|
||||
if r == 'not found'
|
||||
res[:server] = "Directory '/etc/chef' does not exists"
|
||||
else
|
||||
raise(r) unless $?.success?
|
||||
res[:server] = "'/etc/chef' renamed to '#{new_name}'"
|
||||
end
|
||||
rescue => e
|
||||
DevopsLogger.logger.error "Unbootstrap error: " + e.message
|
||||
i += 1
|
||||
sleep(1)
|
||||
retry unless i == 5
|
||||
return e.message
|
||||
return {error: e.message}
|
||||
end
|
||||
nil
|
||||
res
|
||||
end
|
||||
|
||||
def deploy_server_with_tags tags, deploy_info
|
||||
|
||||
@ -6,6 +6,11 @@ When(/^I send GET '(.*)' query$/) do |path|
|
||||
get(path, {}, DEFAULT_HEADERS)
|
||||
end
|
||||
|
||||
When(/^I send GET '(.*)' query with header 'Accept' value '(.*)'$/) do |path, hv|
|
||||
headers = {"Accept" => hv}
|
||||
get(path, {}, headers)
|
||||
end
|
||||
|
||||
When(/^I send GET '(.*)' query with user without privileges$/) do |path|
|
||||
get_without_privileges(path, {}, DEFAULT_HEADERS)
|
||||
end
|
||||
@ -31,9 +36,16 @@ When(/^I send POST '(.*)' query with JSON body$/) do |path, body|
|
||||
res = post_body(path, body, DEFAULT_HEADERS)
|
||||
end
|
||||
|
||||
When(/^I send POST '(.*)' query with body with header 'Accept' value '(.*)'$/) do |path, hv, body|
|
||||
When(/^I send POST '(.*)' query with JSON body with header '(.*)' value '(.*)'$/) do |path, header, hv, body|
|
||||
JSON.parse(body) unless body.strip.empty?
|
||||
headers = DEFAULT_HEADERS.clone
|
||||
headers["Accept"] = hv
|
||||
headers[header] = hv
|
||||
res = post_body(path, body, headers)
|
||||
end
|
||||
|
||||
When(/^I send POST '(.*)' query with body with header '(.*)' value '(.*)'$/) do |path, header, hv, body|
|
||||
headers = DEFAULT_HEADERS.clone
|
||||
headers[header] = hv
|
||||
res = post_body(path, body, headers)
|
||||
end
|
||||
|
||||
@ -57,13 +69,19 @@ When(/^I send DELETE '(.*)' query$/) do |path|
|
||||
delete(path, {}, DEFAULT_HEADERS)
|
||||
end
|
||||
|
||||
When(/^I send DELETE '(.*)' query with JSON body with header 'Accept' value '(.*)'$/) do |path, hv, body|
|
||||
When(/^I send DELETE '(.*)' query with JSON body with header '(.*)' value '(.*)'$/) do |path, header, hv, body|
|
||||
JSON.parse(body) unless body.strip.empty?
|
||||
headers = DEFAULT_HEADERS.clone
|
||||
headers["Accept"] = hv
|
||||
headers[header] = hv
|
||||
res = delete_body(path, body, headers)
|
||||
end
|
||||
|
||||
When(/^I send DELETE '(.*)' query with header '(.*)' value '(.*)'$/) do |path, header, hv|
|
||||
headers = DEFAULT_HEADERS.clone
|
||||
headers[header] = hv
|
||||
res = delete_body(path, nil, headers)
|
||||
end
|
||||
|
||||
When(/^I send DELETE '(.*)' query with JSON body$/) do |path, body|
|
||||
JSON.parse(body) unless body.strip.empty?
|
||||
res = delete_body(path, body, DEFAULT_HEADERS)
|
||||
@ -99,10 +117,10 @@ When(/^I send PUT '(.*)' query with user without privileges$/) do |path|
|
||||
put_without_privileges(path, {}, DEFAULT_HEADERS)
|
||||
end
|
||||
|
||||
When(/^I send PUT '(.*)' query with JSON body with header 'Accept' value '(.*)'$/) do |path, hv, body|
|
||||
When(/^I send PUT '(.*)' query with JSON body with header '(.*)' value '(.*)'$/) do |path, header, hv, body|
|
||||
JSON.parse(body) unless body.strip.empty?
|
||||
headers = DEFAULT_HEADERS.clone
|
||||
headers["Accept"] = hv
|
||||
headers[header] = hv
|
||||
res = put_body(path, body, headers)
|
||||
end
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
Then(/^response array should contains elements like:$/) do |string|
|
||||
src = JSON.parse(string).first
|
||||
src = JSON.parse(string)
|
||||
array = JSON.parse(last_response.body)
|
||||
array.each do |e|
|
||||
src.each do |key, value|
|
||||
@ -44,15 +44,14 @@ Then(/^response should be JSON object like:$/) do |string|
|
||||
end
|
||||
|
||||
Then(/^the array should contains strings '(.*)'$/) do |string|
|
||||
buf = string.split(",")
|
||||
buf = string.split(",").map(&:strip)
|
||||
array = JSON.parse(last_response.body)
|
||||
buf.each do |v|
|
||||
assert array.include?(v), "Array should contains '#{v}'"
|
||||
end
|
||||
res = buf - array
|
||||
assert res.empty?, "Response has no strings '#{res.join("', '")}'"
|
||||
end
|
||||
|
||||
Then(/^the array should not contains strings '(.*)'$/) do |string|
|
||||
buf = string.split(",")
|
||||
buf = string.split(",").map(&:strip)
|
||||
array = JSON.parse(last_response.body)
|
||||
buf.each do |v|
|
||||
assert !array.include?(v), "Array should not contains '#{v}'"
|
||||
|
||||
@ -5,6 +5,7 @@ require "yaml"
|
||||
require "ostruct"
|
||||
require "fileutils"
|
||||
require "./templates/fixtures/fixture_formatter"
|
||||
require "./templates/generators/path_scenarios_generator.rb"
|
||||
|
||||
class Generator < OpenStruct
|
||||
|
||||
@ -15,7 +16,8 @@ class Generator < OpenStruct
|
||||
config_file = ENV["DEVOPS_FEATURES_GENERATOR_CONFIG"] || ENV["CONFIG"] || CONFIG
|
||||
@config = YAML.load_file(File.new(config_file))
|
||||
load_fixtures()
|
||||
super(:config => @config, :formatter => @formatter, :fixtures => @fixtures)
|
||||
@generator = PathScenariosGenerator.new
|
||||
super(:config => @config, :formatter => @formatter, :fixtures => @fixtures, :generator => @generator)
|
||||
end
|
||||
|
||||
def configure!
|
||||
@ -31,6 +33,7 @@ class Generator < OpenStruct
|
||||
templates.each do |input, output|
|
||||
puts "Input: #{input}"
|
||||
if File.exists?(input)
|
||||
begin
|
||||
file_data = File.read(input)
|
||||
if file_data.nil?
|
||||
puts "Data of file '#{input}' is nil"
|
||||
@ -40,20 +43,31 @@ class Generator < OpenStruct
|
||||
FileUtils.mkdir_p(dir) unless File.exists?(dir)
|
||||
File.open(output, "w") {|f| f.write(data)}
|
||||
end
|
||||
rescue => e
|
||||
puts "\tError: #{e.message}"
|
||||
end
|
||||
else
|
||||
puts "WARN: file '#{input}' does not exist"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def clean!(feature_files)
|
||||
def self.clean!
|
||||
dir = "features/api_v2/"
|
||||
if File.exists?(dir)
|
||||
puts "Removing directory '#{dir}'"
|
||||
FileUtils.rm_r(dir)
|
||||
end
|
||||
|
||||
=begin
|
||||
feature_files.each do |feature_file|
|
||||
if File.exists?(feature_file)
|
||||
FileUtils.rm(feature_file)
|
||||
FileUtils.rm_f(feature_file)
|
||||
else
|
||||
puts "WARN: file '#{feature_file}' does not exist"
|
||||
end
|
||||
end
|
||||
=end
|
||||
end
|
||||
|
||||
private
|
||||
@ -63,10 +77,13 @@ class Generator < OpenStruct
|
||||
end
|
||||
|
||||
def load_fixtures
|
||||
puts "Load fixures:"
|
||||
@fixtures = {}
|
||||
Dir["templates/fixtures/*.yml"].each do |fixture_path|
|
||||
fixture_name = File.basename(fixture_path, '.yml')
|
||||
print "\t#{fixture_path}..."
|
||||
@fixtures[fixture_name] = YAML.load_file(fixture_path)
|
||||
puts " ok"
|
||||
end
|
||||
|
||||
@formatter = FixtureFormatter.new(@fixtures)
|
||||
@ -78,7 +95,14 @@ templates = {
|
||||
#list
|
||||
"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/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_bootstrap_template.feature.erb" => "features/api_v2/00_list/10_bootstrap_template.feature",
|
||||
"templates/api_v2/00_list/10_filter.feature.erb" => "features/api_v2/00_list/10_filter.feature",
|
||||
"templates/api_v2/00_list/20_image.feature.erb" => "features/api_v2/00_list/20_image.feature",
|
||||
"templates/api_v2/00_list/20_key.feature.erb" => "features/api_v2/00_list/20_key.feature",
|
||||
"templates/api_v2/00_list/30_project.feature.erb" => "features/api_v2/00_list/30_project.feature",
|
||||
|
||||
#create
|
||||
"templates/api_v2/10_create/00_filter.feature.erb" => "features/api_v2/10_create/00_filter.feature",
|
||||
@ -87,6 +111,7 @@ templates = {
|
||||
"templates/api_v2/10_create/10_image.feature.erb" => "features/api_v2/10_create/10_image.feature",
|
||||
"templates/api_v2/10_create/50_stack.feature.erb" => "features/api_v2/10_create/50_stack.feature",
|
||||
"templates/api_v2/10_create/20_project.feature.erb" => "features/api_v2/10_create/20_project.feature",
|
||||
"templates/api_v2/10_create/21_deploy_env.feature.erb" => "features/api_v2/10_create/21_deploy_env.feature",
|
||||
"templates/api_v2/10_create/30_script.feature.erb" => "features/api_v2/10_create/30_script.feature",
|
||||
"templates/api_v2/10_create/40_deploy_env.feature.erb" => "features/api_v2/10_create/40_deploy_env.feature",
|
||||
"templates/api_v2/10_create/00_user.feature.erb" => "features/api_v2/10_create/00_user.feature",
|
||||
@ -108,11 +133,10 @@ templates = {
|
||||
|
||||
}
|
||||
|
||||
generator = Generator.new.configure!
|
||||
if ARGV.first != 'clean'
|
||||
generator = Generator.new.configure!
|
||||
generator.generate!(templates)
|
||||
else
|
||||
generator.clean!(templates.values)
|
||||
Generator.clean!
|
||||
end
|
||||
|
||||
|
||||
|
||||
@ -7,30 +7,3 @@ path_prefix: ""
|
||||
username_without_privileges: "user_for_testing_"
|
||||
password_without_privileges: "test"
|
||||
|
||||
openstack:
|
||||
flavor: "as_long_as_image"
|
||||
image: "08093b30-8393-42c3-8fb3-c4df56deb967"
|
||||
subnet: "subnet"
|
||||
project:
|
||||
name: "test_openstack"
|
||||
env: "test"
|
||||
|
||||
ec2:
|
||||
flavor: "m1.small"
|
||||
image: "ami-63071b0a"
|
||||
subnet: "subnet"
|
||||
project:
|
||||
name: "test_ec2"
|
||||
env: "test"
|
||||
|
||||
static:
|
||||
project:
|
||||
name: "test_static"
|
||||
env: "test"
|
||||
|
||||
script:
|
||||
name: "cucumber_test_script"
|
||||
|
||||
user:
|
||||
name: "cucumber_test"
|
||||
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
@network @list
|
||||
Feature: Networks
|
||||
|
||||
<% @formatter.get_fixture('providers/without_static').each do |provider| %>
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> networks
|
||||
When I send GET '/v2.0/networks/<%= provider %>' 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:
|
||||
"""
|
||||
[
|
||||
<%= @formatter.json(provider + '/network', spaces: 6) %>
|
||||
]
|
||||
"""
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> networks with header 'Accept' value is not 'application/json'
|
||||
When I send GET '/v2.0/networks/<%= provider %>' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
<% end %>
|
||||
|
||||
@static
|
||||
Scenario: Get list of static networks
|
||||
When I send GET '/v2.0/networks/static' 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 be empty
|
||||
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|provider| "@#{provider}"} %>
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get networks list of unknown provider
|
||||
When I send GET '/v2.0/networks/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get networks list of unknown provider without privileges
|
||||
When I send GET '/v2.0/networks/foo' query with user without privileges
|
||||
Then response should be '401'
|
||||
@ -0,0 +1,18 @@
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|provider| "@#{provider}"} %>
|
||||
@list @bootstrap_template <%= providers.join(" ") %>
|
||||
Feature: Bootstrap templates
|
||||
|
||||
Scenario: Get list bootstrap templates
|
||||
When I send GET '/v2.0/templates' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an array
|
||||
And the array elements should be strings
|
||||
|
||||
Scenario: Get bootstrap templates list with header 'Accept' value is not 'application/json'
|
||||
When I send GET '/v2.0/templates' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
Scenario: Get bootstrap template list without privileges
|
||||
When I send GET '/v2.0/templates' query with user without privileges
|
||||
Then response should be '401'
|
||||
@ -0,0 +1,32 @@
|
||||
@filter @list
|
||||
Feature: Filters
|
||||
|
||||
<% @formatter.get_fixture('providers/without_static').each do |provider| %>
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> filters
|
||||
When I send GET '/v2.0/filter/<%= provider %>/images' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an array
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> filters with header 'Accept' value is not 'application/json'
|
||||
When I send GET '/v2.0/filter/<%= provider %>/images' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Get filter list for <%= provider %> provider without privileges
|
||||
When I send GET '/v2.0/filter/<%= provider %>/images' query with user without privileges
|
||||
Then response should be '401'
|
||||
<% end %>
|
||||
|
||||
@openstack @ec2 @static
|
||||
Scenario: Get filter list of unknown provider
|
||||
When I send GET '/v2.0/filter/foo/images' query
|
||||
Then response should be '404'
|
||||
|
||||
@openstack @ec2 @static
|
||||
Scenario: Get filter list of unknown provider without privileges
|
||||
When I send GET '/v2.0/filter/foo/images' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
@group @list
|
||||
Feature: Groups
|
||||
|
||||
<% @formatter.get_fixture('providers/without_static').each do |provider| %>
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> groups
|
||||
When I send GET '/v2.0/groups/<%= provider %>' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> groups with header 'Accept' value is not 'application/json'
|
||||
When I send GET '/v2.0/groups/<%= provider %>' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Get groups list for <%= provider %> provider without privileges
|
||||
When I send GET '/v2.0/groups/<%= provider %>' query with user without privileges
|
||||
Then response should be '401'
|
||||
<% end %>
|
||||
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|provider| "@#{provider}"} %>
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get groups list of unknown provider
|
||||
When I send GET '/v2.0/groups/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get groups list of unknown provider without privileges
|
||||
When I send GET '/v2.0/groups/foo' query with user without privileges
|
||||
Then response should be '401'
|
||||
@ -1,4 +1,5 @@
|
||||
@user
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|provider| "@#{provider}"} %>
|
||||
@list @user <%= providers.join(" ") %>
|
||||
Feature: list user
|
||||
|
||||
Scenario: Get list of all users
|
||||
@ -9,27 +10,14 @@ Feature: list user
|
||||
And response array should contains elements like:
|
||||
"""
|
||||
[
|
||||
{
|
||||
"email": "test@test.test",
|
||||
"privileges": {
|
||||
"flavor": "rwx",
|
||||
"group": "rwx",
|
||||
"image": "rwx",
|
||||
"project": "rwx",
|
||||
"server": "rwx",
|
||||
"key": "rwx",
|
||||
"user": "rwx",
|
||||
"filter": "rwx",
|
||||
"network": "rwx",
|
||||
"provider": "rwx",
|
||||
"script": "rwx",
|
||||
"templates": "rwx"
|
||||
},
|
||||
"id": "test"
|
||||
}
|
||||
<%= @formatter.json('user/show', spaces: 6) %>
|
||||
]
|
||||
"""
|
||||
|
||||
Scenario: Get list of all users
|
||||
When I send GET '/v2.0/users' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
Scenario: Get list of all users without privileges
|
||||
When I send GET '/v2.0/users' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@ -0,0 +1,106 @@
|
||||
@image @list
|
||||
Feature: List images
|
||||
|
||||
<% @formatter.get_fixture('providers/without_static').each do |provider| %>
|
||||
@<%= provider %>
|
||||
Scenario: Get list mages with provider <%= provider %>
|
||||
When I send GET '/v2.0/images?provider=<%= provider %>' 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:
|
||||
"""
|
||||
<%= @formatter.json(provider + '/image') %>
|
||||
"""
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> images with header 'Accept' value is not 'application/json'
|
||||
When I send GET '/v2.0/images?provider=<%= provider %>' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Get images list for <%= provider %> provider without privileges
|
||||
When I send GET '/v2.0/images?provider=<%= provider %>' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Get images list of <%= provider %> provider
|
||||
When I send GET '/v2.0/images/provider/<%= provider %>' 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:
|
||||
"""
|
||||
<%= @formatter.json(provider + '/provider_image') %>
|
||||
"""
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> images with header 'Accept' value is not 'application/json'
|
||||
When I send GET '/v2.0/images/provider/<%= provider %>' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Get images list for <%= provider %> provider without privileges
|
||||
When I send GET '/v2.0/images/provider/<%= provider %>' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
<% end %>
|
||||
|
||||
@static
|
||||
Scenario: Get list of static provider images
|
||||
When I send GET '/v2.0/images?provider=static' 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 be empty
|
||||
|
||||
@static
|
||||
Scenario: Get list of static images with header 'Accept' value is not 'application/json'
|
||||
When I send GET '/v2.0/images?provider=static' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
@static
|
||||
Scenario: Get images list for static provider without privileges
|
||||
When I send GET '/v2.0/images?provider=static' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|provider| "@#{provider}"} %>
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get images list of unknown provider
|
||||
When I send GET '/v2.0/images?provider=foo' query
|
||||
Then response should be '400'
|
||||
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get images list without privileges
|
||||
When I send GET '/v2.0/images' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get groups list of unknown provider without privileges
|
||||
When I send GET '/v2.0/images?provider=foo' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get list of all images - invalid path
|
||||
When I send GET '/v2.0/images/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get list of images of unknown provider
|
||||
When I send GET '/v2.0/images/provider/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get unknown image
|
||||
When I send GET '/v2.0/image/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get unknown image without privileges
|
||||
When I send GET '/v2.0/image/foo' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get image path
|
||||
When I send GET '/v2.0/image' query
|
||||
Then response should be '404'
|
||||
@ -0,0 +1,21 @@
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|p| "@#{p}"} %>
|
||||
@key @list <%= providers.join(" ") %>
|
||||
Feature: List keys
|
||||
|
||||
Scenario: Get keys
|
||||
When I send GET '/v2.0/keys' 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:
|
||||
"""
|
||||
<%= @formatter.json('key/list_element') %>
|
||||
"""
|
||||
|
||||
Scenario: Get keys list with header 'Accept' value is not 'application/json'
|
||||
When I send GET '/v2.0/keys' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
Scenario: Get keys list without privileges
|
||||
When I send GET '/v2.0/keys' query with user without privileges
|
||||
Then response should be '401'
|
||||
@ -0,0 +1,6 @@
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|provider| "@#{provider}"} %>
|
||||
@project @list <%= providers.join(" ") %>
|
||||
Feature: List projects
|
||||
|
||||
<%= @generator.generate_get_path_scenarios("Show project types", "/v2.0/project_types") {%Q(And the JSON response should be an array\n And the array elements should be strings)} %>
|
||||
|
||||
@ -1,42 +1,26 @@
|
||||
@flavor
|
||||
@flavor @list
|
||||
Feature: Flavors
|
||||
|
||||
@openstack
|
||||
Scenario: Get list of openstack flavors
|
||||
When I send GET '/v2.0/flavors/openstack' query
|
||||
<% @formatter.get_fixture('providers/without_static').each do |provider| %>
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> flavors
|
||||
When I send GET '/v2.0/flavors/<%= provider %>' 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": "flavor_id",
|
||||
"v_cpus": "v_cpus",
|
||||
"ram": "ram",
|
||||
"disk": "disk"
|
||||
}
|
||||
<%= @formatter.json(provider + '/flavor', spaces: 6) %>
|
||||
]
|
||||
"""
|
||||
|
||||
@ec2
|
||||
Scenario: Get list of ec2 flavors
|
||||
When I send GET '/v2.0/flavors/ec2' 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": "t1.micro",
|
||||
"cores": 2,
|
||||
"disk": 0,
|
||||
"name": "Micro Instance",
|
||||
"ram": 613
|
||||
}
|
||||
]
|
||||
"""
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> flavors with header 'Accept' value is not 'application/json'
|
||||
When I send GET '/v2.0/flavors/<%= provider %>' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
<% end %>
|
||||
|
||||
@static
|
||||
Scenario: Get list of static flavors
|
||||
@ -46,10 +30,13 @@ Feature: Flavors
|
||||
And the JSON response should be an array
|
||||
And response array should be empty
|
||||
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|provider| "@#{provider}"} %>
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get flavors list of unknown provider
|
||||
When I send GET '/v2.0/flavors/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Get flavors list of unknown provider without privileges
|
||||
When I send GET '/v2.0/flavors/foo' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
@stack_preset
|
||||
@stack_preset @list
|
||||
Feature: stack template preset list
|
||||
|
||||
Scenario: Get list of all stack template presets
|
||||
|
||||
@ -1,192 +1,74 @@
|
||||
@filter @image @project
|
||||
Feature: Filters
|
||||
|
||||
@openstack
|
||||
Scenario: Add openstack image filter with user without privileges
|
||||
When I send PUT '/v2.0/filter/openstack/image' query with user without privileges
|
||||
<% @formatter.get_fixture('providers/without_static').each do |provider| %>
|
||||
<% image = @formatter.get_fixture(provider + "/image")["id"] %>
|
||||
@<%= provider %>
|
||||
Scenario: Add <%= provider %> images filter with user without privileges
|
||||
When I send PUT '/v2.0/filter/<%= provider %>/image' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@openstack
|
||||
Scenario: Add openstack image filter with header 'Accept' value 'text/*'
|
||||
When I send PUT '/v2.0/filter/openstack/image' query with JSON body with header 'Accept' value 'text/*'
|
||||
@<%= provider %>
|
||||
Scenario: Update images filter with JSON body with header 'Accept' value not 'application/json'
|
||||
When I send PUT '/v2.0/filter/<%= provider %>/image' query with JSON body with header 'Accept' value 'application/xml'
|
||||
"""
|
||||
[
|
||||
"<%= @config["openstack"]["image"] %>"
|
||||
"<%= image %>"
|
||||
]
|
||||
"""
|
||||
Then response should be '406'
|
||||
|
||||
@openstack
|
||||
Scenario: Add openstack image filter without header 'Content-Type'
|
||||
When I send PUT '/v2.0/filter/openstack/image' query with JSON body without header 'Content-Type'
|
||||
@<%= provider %>
|
||||
Scenario: Add <%= provider %> image filter without header 'Content-Type'
|
||||
When I send PUT '/v2.0/filter/<%= provider %>/image' query with JSON body without header 'Content-Type'
|
||||
"""
|
||||
[
|
||||
"<%= @config["openstack"]["image"] %>"
|
||||
"<%= image %>"
|
||||
]
|
||||
"""
|
||||
Then response should be '415'
|
||||
|
||||
@openstack
|
||||
Scenario: Add openstack image filter, invalid body: empty
|
||||
When I send PUT '/v2.0/filter/openstack/image' query with JSON body
|
||||
<% ["", "{}", "[{}]", "[[]]", "[null]"].each do |body| %>
|
||||
@<%= provider %>
|
||||
Scenario: Add <%= provider %> image filter, invalid body: '<%= body %>'
|
||||
When I send PUT '/v2.0/filter/<%= provider %>/image' query with JSON body
|
||||
"""
|
||||
<%= body %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
<% end %>
|
||||
|
||||
@openstack
|
||||
Scenario: Add openstack image filter, invalid body: hash
|
||||
When I send PUT '/v2.0/filter/openstack/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"foo": "foo"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Add openstack image filter, invalid body: element is hash
|
||||
When I send PUT '/v2.0/filter/openstack/image' query with JSON body
|
||||
"""
|
||||
[{
|
||||
"foo": "foo"
|
||||
}]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Add openstack image filter, invalid body: element is array
|
||||
When I send PUT '/v2.0/filter/openstack/image' query with JSON body
|
||||
@<%= provider %>
|
||||
Scenario: Add <%= provider %> image filter
|
||||
When I send PUT '/v2.0/filter/<%= provider %>/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
[]
|
||||
]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Add openstack image filter, invalid body: element is null
|
||||
When I send PUT '/v2.0/filter/openstack/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
null
|
||||
]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Add openstack image filter
|
||||
When I send PUT '/v2.0/filter/openstack/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
"<%= @config["openstack"]["image"] %>"
|
||||
"<%= image %>"
|
||||
]
|
||||
"""
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
And the object should contains key 'images' with array and array should contains strings '<%= @config["openstack"]["image"] %>'
|
||||
And the object should contains key 'images' with array and array should contains strings '<%= image %>'
|
||||
|
||||
@openstack
|
||||
Scenario: Add openstack image filter with invalid JSON
|
||||
When I send PUT '/v2.0/filter/openstack/image' query with body
|
||||
"""
|
||||
[
|
||||
"<%= @config["openstack"]["image"] %>",
|
||||
]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Add ec2 image filter with user without privileges
|
||||
When I send PUT '/v2.0/filter/ec2/image' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@ec2
|
||||
Scenario: Add ec2 image filter with header 'Accept' value 'text/*'
|
||||
When I send PUT '/v2.0/filter/ec2/image' query with JSON body with header 'Accept' value 'text/*'
|
||||
"""
|
||||
[
|
||||
"<%= @config["ec2"]["image"] %>"
|
||||
]
|
||||
"""
|
||||
Then response should be '406'
|
||||
|
||||
@ec2
|
||||
Scenario: Add ec2 image filter without header 'Content-Type'
|
||||
When I send PUT '/v2.0/filter/ec2/image' query with JSON body without header 'Content-Type'
|
||||
"""
|
||||
[
|
||||
"<%= @config["ec2"]["image"] %>"
|
||||
]
|
||||
"""
|
||||
Then response should be '415'
|
||||
|
||||
@ec2
|
||||
Scenario: Add ec2 image filter, invalid body: empty
|
||||
When I send PUT '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Add ec2 image filter, invalid body: hash
|
||||
When I send PUT '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"foo": "foo"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Add ec2 image filter, invalid body: element is hash
|
||||
When I send PUT '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
[{
|
||||
"foo": "foo"
|
||||
}]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Add ec2 image filter, invalid body: element is array
|
||||
When I send PUT '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
[]
|
||||
]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Add ec2 image filter, invalid body: element is null
|
||||
When I send PUT '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
null
|
||||
]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Add ec2 image filter
|
||||
When I send PUT '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
"<%= @config["ec2"]["image"] %>"
|
||||
]
|
||||
"""
|
||||
@<%= provider %>
|
||||
Scenario: Get new <%= provider %> image filter and check value '<%= image %>'
|
||||
When I send GET '/v2.0/filter/<%= provider %>/images' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
And the object should contains key 'images' with array and array should contains strings '<%= @config["ec2"]["image"] %>'
|
||||
And the JSON response should be an array
|
||||
And the array elements should be strings
|
||||
And the array should contains strings '<%= image %>'
|
||||
|
||||
@ec2
|
||||
Scenario: Add ec2 image filter with invalid JSON
|
||||
When I send PUT '/v2.0/filter/ec2/image' query with body
|
||||
@<%= provider %>
|
||||
Scenario: Add <%= provider %> image filter with invalid JSON
|
||||
When I send PUT '/v2.0/filter/<%= provider %>/image' query with body
|
||||
"""
|
||||
[
|
||||
"<%= @config["ec2"]["image"] %>",
|
||||
"<%= image %>",
|
||||
]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
<% end %>
|
||||
|
||||
|
||||
@ -1,34 +1,44 @@
|
||||
@key
|
||||
Feature: Add new script
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|p| "@#{p}"} %>
|
||||
@key <%= providers.join(" ") %>
|
||||
Feature: Add new key
|
||||
|
||||
Scenario: Add new key without file_name
|
||||
<% new_key = @formatter.get_fixture('key/new') %>
|
||||
<% new_key.keys.each do |key| %>
|
||||
<% [[], {}, nil].each do |value| %>
|
||||
Scenario: Add new key with <%= key %> value <%= value %>
|
||||
When I send POST '/v2.0/key' query with JSON body
|
||||
"""
|
||||
<%= @formatter.json('key/invalid/blank_file_name', spaces: 6) %>
|
||||
<%= @formatter.json('key/new', {spaces: 4, value: {key => value}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
And response error should be "Parameter 'file_name' must be a not empty string"
|
||||
And response error should be "Parameter '<%= key %>' should be a not empty string"
|
||||
|
||||
Scenario: Add new key without key_name
|
||||
Scenario: Add new key without <%= key %>
|
||||
When I send POST '/v2.0/key' query with JSON body
|
||||
"""
|
||||
<%= @formatter.json('key/invalid/blank_key_name', spaces: 6) %>
|
||||
<%= @formatter.json('key/new', {spaces: 4, without_field: key}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
And response error should be "Parameter 'key_name' should be a not empty string"
|
||||
And response error should be "Parameter '<%= key %>' should be a not empty string"
|
||||
|
||||
Scenario: Add new key without content
|
||||
When I send POST '/v2.0/key' query with JSON body
|
||||
<% end #value %>
|
||||
<% end %>
|
||||
|
||||
Scenario: Add new key with header 'Accept' value is not 'application/json'
|
||||
When I send POST '/v2.0/key' query with JSON body with header 'Accept' value 'application/xml'
|
||||
"""
|
||||
<%= @formatter.json('key/invalid/blank_content', spaces: 6) %>
|
||||
<%= @formatter.json('key/new') %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
And response error should be "Parameter 'content' should be a not empty string"
|
||||
Then response should be '406'
|
||||
|
||||
Scenario: Add new key without privileges
|
||||
When I send POST '/v2.0/key' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
Scenario: Add new key
|
||||
When I send POST '/v2.0/key' query with JSON body
|
||||
"""
|
||||
<%= @formatter.json('key/valid', spaces: 6) %>
|
||||
<%= @formatter.json('key/new') %>
|
||||
"""
|
||||
Then response should be '201'
|
||||
|
||||
|
||||
@ -4,32 +4,47 @@ Feature: create user
|
||||
Scenario: create user with user without privileges
|
||||
When I send POST '/v2.0/user' query with JSON body with user without privileges
|
||||
"""
|
||||
{
|
||||
"username": "<%= @config["user"]["name"] %>",
|
||||
"email": "<%= @config["user"]["name"] %>@test.test",
|
||||
"password": "<%= @config["user"]["name"] %>"
|
||||
}
|
||||
<%= @formatter.json('user/create', spaces: 4) %>
|
||||
"""
|
||||
Then response should be '401'
|
||||
|
||||
Scenario: create user without header 'Content-Type'
|
||||
When I send POST '/v2.0/user' query with JSON body without header 'Content-Type'
|
||||
"""
|
||||
{
|
||||
"username": "<%= @config["user"]["name"] %>",
|
||||
"email": "<%= @config["user"]["name"] %>@test.test",
|
||||
"password": "<%= @config["user"]["name"] %>"
|
||||
}
|
||||
<%= @formatter.json('user/create', spaces: 4) %>
|
||||
"""
|
||||
Then response should be '415'
|
||||
|
||||
Scenario: create user with header 'Accept' value is not 'application/json'
|
||||
When I send POST '/v2.0/user' query with body with header 'Accept' value 'application/xml'
|
||||
"""
|
||||
<%= @formatter.json('user/create', spaces: 4) %>
|
||||
"""
|
||||
Then response should be '406'
|
||||
|
||||
Scenario: create user, invalid body: empty
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
<% ["{}", "[]"].each do |k| %>
|
||||
<% invalid_name = "foo]&" %>
|
||||
Scenario: create user with invalid name '<% invalid_name %>'
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
<%= @formatter.json('user/create', {spaces: 4, value: {"username" => invalid_name}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
<% long_name = "a"*250 %>
|
||||
Scenario: create user with long name '<% long_name %>'
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
<%= @formatter.json('user/create', {spaces: 4, value: {"username" => long_name}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
<% [{}, []].each do |k| %>
|
||||
Scenario: create user, invalid body: body is a '<%= k %>'
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
@ -38,85 +53,31 @@ Feature: create user
|
||||
Then response should be '400'
|
||||
|
||||
<% end %>
|
||||
<% elements = ["{}", "[]", "null" ] %>
|
||||
<% elements = [{}, [], nil ] %>
|
||||
<% fields = @formatter.get_fixture('user/create').keys.map{|k| k.to_s} %>
|
||||
<% fields.each do |field| %>
|
||||
<% elements.each do |k| %>
|
||||
Scenario: create user, invalid body: username is a '<%= k %>'
|
||||
Scenario: create user, invalid body: <%= field %> is a '<%= k %>'
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
{
|
||||
"username": <%= k %>,
|
||||
"email": "<%= @config["user"]["name"] %>@test.test",
|
||||
"password": "<%= @config["user"]["name"] %>"
|
||||
}
|
||||
<%= @formatter.json('user/create', {spaces: 4, value: {field => k}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
Scenario: create user, invalid body: without <%= field %>
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
<%= @formatter.json('user/create', {spaces: 4, without_field: field}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
<% end %>
|
||||
<% elements.each do |k| %>
|
||||
Scenario: create user, invalid body: password is a '<%= k %>'
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
{
|
||||
"username": "<%= @config["user"]["name"] %>",
|
||||
"email": "<%= @config["user"]["name"] %>@test.test",
|
||||
"password": <%= k %>
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
<% end %>
|
||||
<% elements.each do |k| %>
|
||||
Scenario: create user, invalid body: email is a '<%= k %>'
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
{
|
||||
"username": "<%= @config["user"]["name"] %>",
|
||||
"email": <%= k %>,
|
||||
"password": "<%= @config["user"]["name"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
<% end %>
|
||||
|
||||
Scenario: create user, invalid body: without username
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
{
|
||||
"email": "<%= @config["user"]["name"] %>@test.test",
|
||||
"password": "<%= @config["user"]["name"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
Scenario: create user, invalid body: without email
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
{
|
||||
"username": "<%= @config["user"]["name"] %>",
|
||||
"password": "<%= @config["user"]["name"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
Scenario: create user, invalid body: without password
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
{
|
||||
"email": "<%= @config["user"]["name"] %>@test.test",
|
||||
"username": "<%= @config["user"]["name"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
Scenario: create user
|
||||
When I send POST '/v2.0/user' query with JSON body
|
||||
"""
|
||||
{
|
||||
"username": "<%= @config["user"]["name"] %>",
|
||||
"email": "<%= @config["user"]["name"] %>@test.test",
|
||||
"password": "<%= @config["user"]["name"] %>"
|
||||
}
|
||||
<%= @formatter.json('user/create', spaces: 4) %>
|
||||
"""
|
||||
Then response should be '201'
|
||||
And the Content-Type header should include 'application/json'
|
||||
|
||||
@ -1,552 +1,85 @@
|
||||
@image @project
|
||||
Feature: Manage images
|
||||
|
||||
Scenario: Get list of all images
|
||||
When I send GET '/v2.0/images' 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:
|
||||
"""
|
||||
[
|
||||
{
|
||||
"provider": "foo_provider",
|
||||
"name": "foo_name",
|
||||
"remote_user": "foo_user",
|
||||
"bootstrap_template": "foo_template",
|
||||
"id": "foo_id"
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
Scenario: Get list of all images without privileges
|
||||
When I send GET '/v2.0/images' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
Scenario: Get list of all images - invalid path
|
||||
When I send GET '/v2.0/images/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
@openstack
|
||||
Scenario: Get list of openstack images
|
||||
When I send GET '/v2.0/images?provider=openstack' 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:
|
||||
"""
|
||||
[
|
||||
{
|
||||
"provider": "foo_provider",
|
||||
"name": "foo_name",
|
||||
"remote_user": "foo_user",
|
||||
"bootstrap_template": "foo_template",
|
||||
"id": "foo_id"
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
@openstack
|
||||
Scenario: Get list of openstack images (provider)
|
||||
When I send GET '/v2.0/images/provider/openstack' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an array
|
||||
|
||||
@openstack
|
||||
Scenario: Get images list of openstack without privileges
|
||||
When I send GET '/v2.0/images/provider/openstack' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@ec2
|
||||
Scenario: Get list of ec2 images
|
||||
When I send GET '/v2.0/images?provider=ec2' 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:
|
||||
"""
|
||||
[
|
||||
{
|
||||
"provider": "foo_provider",
|
||||
"name": "foo_name",
|
||||
"remote_user": "foo_user",
|
||||
"bootstrap_template": "foo_template",
|
||||
"id": "foo_id"
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
@ec2
|
||||
Scenario: Get list of ec2 images (provider)
|
||||
When I send GET '/v2.0/images/provider/ec2' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an array
|
||||
|
||||
@ec2
|
||||
Scenario: Get images list of ec2 without privileges
|
||||
When I send GET '/v2.0/images/provider/ec2' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
Scenario: Get list of images of unknown provider
|
||||
When I send GET '/v2.0/images/provider/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
Scenario: Get images list without privileges
|
||||
When I send GET '/v2.0/images' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
Scenario: Get unknown image
|
||||
When I send GET '/v2.0/image/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
Scenario: Get unknown image without privileges
|
||||
When I send GET '/v2.0/image/foo' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with ec2 provider
|
||||
<% providers = @formatter.get_fixture('providers/without_static') %>
|
||||
<% providers.each do |provider| %>
|
||||
<% other_providers = providers.clone - [provider] %>
|
||||
<% other_providers.each do |oprovider| %>
|
||||
@<%= provider %>
|
||||
Scenario: Create <%= provider %> image with '<%= oprovider %>' provider (invalid image id for provider)
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {"provider" => oprovider}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid provider
|
||||
<% end #other providers%>
|
||||
<% image = @formatter.get_fixture(provider + '/image') %>
|
||||
<% image.keys.each do |key| %>
|
||||
<% [[], {}].each do |invalid_value| %>
|
||||
@<%= provider %>
|
||||
Scenario: Create <%= provider %> image with invalid <%= key %> value: '<%= invalid_value %>'
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "foo",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {key => invalid_value}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid provider - array
|
||||
<% end #invalid values%>
|
||||
|
||||
<% end # keys%>
|
||||
<% (image.keys - ["bootstrap_template"]).each do |key| %>
|
||||
@<%= provider %>
|
||||
Scenario: Create <%= provider %> image with invalid <%= key %> value: 'nil'
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": ["foo"],
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {key => nil}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid provider - hash
|
||||
<% end %>
|
||||
|
||||
<% (image.keys - ["name", "remote_user"]).each do |key| %>
|
||||
@<%= provider %>
|
||||
Scenario: Create <%= provider %> image with invalid <%= key %> value: 'foo'
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": {},
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {key => "foo"}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid name - hash
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": {},
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
<% end %>
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid name - array
|
||||
@<%= provider %>
|
||||
Scenario: Create <%= provider %> image
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": [],
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid remote_user - hash
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": {},
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid remote_user - array
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": [],
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid bootstrap_template - array
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": [],
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid bootstrap_template - hash
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": {},
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid bootstrap_template - unknown
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "unknown",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid id - array
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": []
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image with invalid id - hash
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": {}
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Create openstack image
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image') %>
|
||||
"""
|
||||
Then response should be '201'
|
||||
And the Content-Type header should include 'application/json'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with openstack provider
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid provider
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "foo",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid provider - array
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": ["foo"],
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid provider - hash
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": {},
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid name - hash
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": {},
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid name - array
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": [],
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid remote_user - hash
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": {},
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid remote_user - array
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": [],
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid bootstrap_template - array
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": [],
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid bootstrap_template - hash
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": {},
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid bootstrap_template - unknown
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": "unknown",
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid id - array
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": []
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image with invalid id - hash
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": {}
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Create ec2 image
|
||||
When I send POST '/v2.0/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '201'
|
||||
And the Content-Type header should include 'application/json'
|
||||
|
||||
@ec2
|
||||
Scenario: Get info for single ec2 image
|
||||
When I send GET '/v2.0/image/<%= @config["ec2"]["image"] %>' query
|
||||
@<%= provider %>
|
||||
Scenario: Check new <%= provider %> image
|
||||
When I send GET '/v2.0/image/<%= image["id"] %>' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
And response should be JSON object like:
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image') %>
|
||||
"""
|
||||
|
||||
@ec2
|
||||
Scenario: Get ec2 image without privileges
|
||||
When I send GET '/v2.0/image/<%= @config["ec2"]["image"] %>' query with user without privileges
|
||||
@<%= provider %>
|
||||
Scenario: Get <%= provider %> image without privileges
|
||||
When I send GET '/v2.0/image/<%= image["id"] %>' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@openstack
|
||||
Scenario: Get info for single openstack image
|
||||
When I send GET '/v2.0/image/<%= @config["openstack"]["image"] %>' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
And response should be JSON object like:
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
@<%= provider %>
|
||||
Scenario: Get list of <%= provider %> images with header 'Accept' value is not 'application/json'
|
||||
When I send GET '/v2.0/image/<%= image["id"] %>' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
@openstack
|
||||
Scenario: Get openstack image without privileges
|
||||
When I send GET '/v2.0/image/<%= @config["openstack"]["image"] %>' query with user without privileges
|
||||
Then response should be '401'
|
||||
<% end %>
|
||||
|
||||
Scenario: Get info for single unknown image
|
||||
When I send GET '/v2.0/image/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
Scenario: Get image path
|
||||
When I send GET '/v2.0/image' query
|
||||
Then response should be '404'
|
||||
|
||||
@ -1,32 +1,12 @@
|
||||
@project
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|provider| "@#{provider}"} %>
|
||||
@project <%= providers.join(" ") %>
|
||||
Feature: create project
|
||||
|
||||
@openstack
|
||||
Scenario: Create project <%= @config["openstack"]["project"]["name"] %>
|
||||
<% project = @formatter.get_fixture('project') %>
|
||||
Scenario: Create project <%= project["name"] %>
|
||||
When I send POST '/v2.0/project' query with JSON body
|
||||
"""
|
||||
{
|
||||
"deploy_envs": [
|
||||
{
|
||||
"identifier": "<%= @config["openstack"]["project"]["env"] %>",
|
||||
"run_list": [],
|
||||
"expires": null,
|
||||
"provider": "openstack",
|
||||
"users": [
|
||||
"<%= @config["username"] %>"
|
||||
],
|
||||
"flavor": "<%= @config["openstack"]["flavor"] %>",
|
||||
"image": "<%= @config["openstack"]["image"] %>",
|
||||
"subnets": [
|
||||
"<%= @config["openstack"]["subnet"] %>"
|
||||
],
|
||||
"groups": [
|
||||
"default"
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "<%= @config["openstack"]["project"]["name"] %>"
|
||||
}
|
||||
<%= @formatter.json('project') %>
|
||||
"""
|
||||
Then response should be '201'
|
||||
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
@project @deploy_env
|
||||
Feature: create deploy env in project
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
@user
|
||||
Feature: change user privileges and password
|
||||
|
||||
<% %w{password email}.each do |k| %>
|
||||
<% val = (k == "email" ? "#{@config["user"]["name"]}@test.test" : @config["user"]["name"]) %>
|
||||
<% user_hash = @formatter.get_fixture('user/create') %>
|
||||
<% username = user_hash["username"] %>
|
||||
<% update_user_hash = @formatter.get_fixture('user/update') %>
|
||||
<% update_user_hash.keys.each do |k| %>
|
||||
Scenario: change user <%= k %> with user without privileges
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>/<%= k %>' query with JSON body with user without privileges
|
||||
When I send PUT '/v2.0/user/<%= username %>/<%= k %>' query with JSON body with user without privileges
|
||||
"""
|
||||
{
|
||||
"<%= k %>": "<%= val %>"
|
||||
"<%= k %>": "<%= update_user_hash[k] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '401'
|
||||
@ -16,29 +18,29 @@ Feature: change user privileges and password
|
||||
When I send PUT '/v2.0/user/root/<%= k %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"<%= k %>": "<%= val %>"
|
||||
"<%= k %>": "<%= update_user_hash[k] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '401'
|
||||
|
||||
Scenario: change user <%= k %> without header 'Content-Type'
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>/<%= k %>' query with JSON body without header 'Content-Type'
|
||||
When I send PUT '/v2.0/user/<%= username %>/<%= k %>' query with JSON body without header 'Content-Type'
|
||||
"""
|
||||
{
|
||||
"<%= k %>": "<%= val %>"
|
||||
"<%= k %>": "<%= update_user_hash[k] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '415'
|
||||
|
||||
Scenario: change user <%= k %>, invalid body: empty
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>/<%= k %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>/<%= k %>' query with JSON body
|
||||
"""
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
<% ["{}", "[]", ""].each do |body| %>
|
||||
<% ["", "[]"].each do |body| %>
|
||||
Scenario: change user <%= k %>, invalid body: body is a '<%= body %>'
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>/<%= k %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>/<%= k %>' query with JSON body
|
||||
"""
|
||||
<%= body %>
|
||||
"""
|
||||
@ -47,7 +49,7 @@ Feature: change user privileges and password
|
||||
<% elements = ["{}", "[]", "null" ] %>
|
||||
<% elements.each do |value| %>
|
||||
Scenario: change user <%= k %>, invalid body: <%= k %> is a '<%= value %>'
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>/<%= k %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>/<%= k %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"<%= k %>": <%= value %>
|
||||
@ -57,10 +59,10 @@ Feature: change user privileges and password
|
||||
<% end %>
|
||||
|
||||
Scenario: change user <%= k %>
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>/<%= k %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>/<%= k %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"<%= k %>": "<%= val %>"
|
||||
"<%= k %>": "<%= update_user_hash[k] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '200'
|
||||
@ -69,115 +71,93 @@ Feature: change user privileges and password
|
||||
<% end %>
|
||||
|
||||
Scenario: change user privileges with user without privileges
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body with user without privileges
|
||||
When I send PUT '/v2.0/user/<%= username %>' query with JSON body with user without privileges
|
||||
"""
|
||||
{}
|
||||
<%= @formatter.json('user/privileges', {spaces: 4}) %>
|
||||
"""
|
||||
Then response should be '401'
|
||||
|
||||
Scenario: change root privileges
|
||||
When I send PUT '/v2.0/user/root' query with JSON body
|
||||
"""
|
||||
{}
|
||||
<%= @formatter.json('user/privileges', {spaces: 4}) %>
|
||||
"""
|
||||
Then response should be '401'
|
||||
|
||||
Scenario: change user privileges without header 'Content-Type'
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body without header 'Content-Type'
|
||||
When I send PUT '/v2.0/user/<%= username %>' query with JSON body without header 'Content-Type'
|
||||
"""
|
||||
{}
|
||||
<%= @formatter.json('user/privileges', {spaces: 4}) %>
|
||||
"""
|
||||
Then response should be '415'
|
||||
|
||||
<% ["[]", ""].each do |body| %>
|
||||
Scenario: change user privileges, invalid body: body is a '<%= body %>'
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body
|
||||
Scenario: change user privileges with header 'Accept' value is not application/json
|
||||
When I send PUT '/v2.0/user/<%= username %>' query with JSON body with header 'Accept' value 'application/xml'
|
||||
"""
|
||||
<%= body %>
|
||||
<%= @formatter.json('user/privileges', {spaces: 4}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
<% end %>
|
||||
Then response should be '406'
|
||||
|
||||
<% elements = ["{}", "[]" ] %>
|
||||
<% elements.each do |value| %>
|
||||
Scenario: change user privileges, invalid body: cmd is a '<%= value %>'
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"cmd": "<%= value %>",
|
||||
"privileges": "r"
|
||||
}
|
||||
<%= @formatter.json('user/privileges_update', {spaces: 4, value: {"cmd" => value, "privileges" => "r"}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
Scenario: change user privileges, invalid body: privileges is a '<%= value %>'
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"cmd": "all",
|
||||
"privileges": "<%= value %>"
|
||||
}
|
||||
<%= @formatter.json('user/privileges_update', {spaces: 4, value: {"cmd" => "foo", "privileges" => value}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
<% end %>
|
||||
|
||||
Scenario: change user privileges: foo - r
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"cmd": "foo",
|
||||
"privileges": "r"
|
||||
}
|
||||
<%= @formatter.json('user/privileges_update', {spaces: 4, value: {"cmd" => "foo", "privileges" => "r"}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
<% %w{foo, rr, rwwww, rwxxx, rwf}.each do |priv| %>
|
||||
Scenario: change user privileges: all - <%= priv %>
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"cmd": "all",
|
||||
"privileges": "<%= priv %>"
|
||||
}
|
||||
<%= @formatter.json('user/privileges_update', {spaces: 4, value: {"cmd" => "all", "privileges" => priv}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
<% end %>
|
||||
|
||||
<% privs = %w{r w x rw rx wx rwx} %>
|
||||
|
||||
<% %w{flavor group image project server key user filter network provider script templates all}.each do |cmd| %>
|
||||
<% privs = @formatter.get_fixture('user/privileges_values') %>
|
||||
<% (@formatter.get_fixture('user/privileges').keys.map(&:to_s) << "all").each do |cmd| %>
|
||||
<% privs.each do |priv| %>
|
||||
Scenario: change user privileges: <%= cmd %> - <%= priv %>
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"cmd": "<%= cmd %>",
|
||||
"privileges": "<%= priv %>"
|
||||
}
|
||||
<%= @formatter.json('user/privileges_update', {spaces: 4, value: {"cmd" => cmd, "privileges" => priv}}) %>
|
||||
"""
|
||||
Then response should be '200'
|
||||
<% end %>
|
||||
Scenario: change user privileges: <%= cmd %> - without privileges
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"cmd": "<%= cmd %>"
|
||||
}
|
||||
<%= @formatter.json('user/privileges_update', {spaces: 4, value: {"cmd" => cmd}, without_field: "privileges"}) %>
|
||||
"""
|
||||
Then response should be '200'
|
||||
|
||||
Scenario: change user privileges: <%= cmd %> - ' '
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"cmd": "<%= cmd %>",
|
||||
"privileges": " "
|
||||
}
|
||||
<%= @formatter.json('user/privileges_update', {spaces: 4, value: {"cmd" => cmd, "privileges" => " "}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
<% end %>
|
||||
|
||||
Scenario: change user privileges: set default privileges
|
||||
When I send PUT '/v2.0/user/<%= @config["user"]["name"] %>' query with JSON body
|
||||
When I send PUT '/v2.0/user/<%= username %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
}
|
||||
|
||||
@ -1,171 +1,62 @@
|
||||
@image @project
|
||||
Feature: Update images
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with ec2 provider
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
<% providers = @formatter.get_fixture('providers/without_static') %>
|
||||
<% providers.each do |provider| %>
|
||||
<% image = @formatter.get_fixture(provider + '/image') %>
|
||||
<% other_providers = providers.clone - [provider] %>
|
||||
<% other_providers.each do |oprovider| %>
|
||||
@<%= provider %>
|
||||
Scenario: Update <%= provider %> image with '<%= oprovider %>' provider (invalid image id for provider)
|
||||
When I send PUT '/v2.0/image/<%= image["id"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {"provider" => oprovider}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid provider
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
<% end #other providers%>
|
||||
|
||||
<% (image.keys - ["id"]).each do |key| %>
|
||||
<% [[], {}].each do |invalid_value| %>
|
||||
@<%= provider %>
|
||||
Scenario: Update <%= provider %> image with invalid <%= key %> value: '<%= invalid_value %>'
|
||||
When I send PUT '/v2.0/image/<%= image["id"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "foo",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {key => invalid_value}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid provider - array
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
<% end #invalid values%>
|
||||
|
||||
<% end # keys%>
|
||||
<% (image.keys - ["bootstrap_template", "id"]).each do |key| %>
|
||||
@<%= provider %>
|
||||
Scenario: Update <%= provider %> image with invalid <%= key %> value: 'nil'
|
||||
When I send PUT '/v2.0/image/<%= image["id"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": ["foo"],
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {key => nil}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid provider - hash
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
<% end %>
|
||||
|
||||
<% (image.keys - ["name", "remote_user", "id"]).each do |key| %>
|
||||
@<%= provider %>
|
||||
Scenario: Update <%= provider %> image with invalid <%= key %> value: 'foo'
|
||||
When I send PUT '/v2.0/image/<%= image["id"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": {},
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {key => "foo"}}) %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid name - hash
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": {},
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
<% end %>
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid name - array
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
<% [[], {}, "foo", nil].each do |value| %>
|
||||
@<%= provider %>
|
||||
Scenario: Update <%= provider %> image with invalid id value: '<%= value %>'
|
||||
When I send PUT '/v2.0/image/<%= image["id"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": [],
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid remote_user - hash
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": {},
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid remote_user - array
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": [],
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid bootstrap_template - array
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": [],
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid bootstrap_template - hash
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": {},
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid bootstrap_template - unknown
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "unknown",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid id - array
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": []
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {"id" => value}}) %>
|
||||
"""
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
@ -173,21 +64,16 @@ Feature: Update images
|
||||
And response should be JSON object like:
|
||||
"""
|
||||
{
|
||||
"message" : "Image '<%= @config["openstack"]["image"] %>' has been updated"
|
||||
"message" : "Image '<%= image["id"] %>' has been updated"
|
||||
}
|
||||
"""
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image with invalid id - hash
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
<% end %>
|
||||
|
||||
Scenario: Update <%= provider %> image without id
|
||||
When I send PUT '/v2.0/image/<%= image["id"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": {}
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {without_field: "id"}) %>
|
||||
"""
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
@ -195,21 +81,15 @@ Feature: Update images
|
||||
And response should be JSON object like:
|
||||
"""
|
||||
{
|
||||
"message" : "Image '<%= @config["openstack"]["image"] %>' has been updated"
|
||||
"message" : "Image '<%= image["id"] %>' has been updated"
|
||||
}
|
||||
"""
|
||||
|
||||
@openstack
|
||||
Scenario: Update openstack image
|
||||
When I send PUT '/v2.0/image/<%= @config["openstack"]["image"] %>' query with JSON body
|
||||
@<%= provider %>
|
||||
Scenario: Update <%= provider %> image
|
||||
When I send PUT '/v2.0/image/<%= image["id"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "freebsd-10.0",
|
||||
"remote_user": "root",
|
||||
"bootstrap_template": "chef_freebsd",
|
||||
"id": "<%= @config["openstack"]["image"] %>"
|
||||
}
|
||||
<%= @formatter.json(provider + '/image') %>
|
||||
"""
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
@ -217,175 +97,15 @@ Feature: Update images
|
||||
And response should be JSON object like:
|
||||
"""
|
||||
{
|
||||
"message" : "Image '<%= @config["openstack"]["image"] %>' has been updated"
|
||||
"message" : "Image '<%= image["id"] %>' has been updated"
|
||||
}
|
||||
"""
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with openstack provider
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
@<%= provider %>
|
||||
Scenario: Update <%= provider %> image with bootstrap_template null
|
||||
When I send PUT '/v2.0/image/<%= image["id"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "openstack",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid provider
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "foo",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid provider - array
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": ["foo"],
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid provider - hash
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": {},
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid name - hash
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": {},
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid name - array
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": [],
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid remote_user - hash
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": {},
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid remote_user - array
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": [],
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid bootstrap_template - array
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": [],
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid bootstrap_template - hash
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": {},
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid bootstrap_template - unknown
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": "unknown",
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid id - array
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": []
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {"bootstrap_template" => nil}}) %>
|
||||
"""
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
@ -393,21 +113,15 @@ Feature: Update images
|
||||
And response should be JSON object like:
|
||||
"""
|
||||
{
|
||||
"message" : "Image '<%= @config["openstack"]["image"] %>' has been updated"
|
||||
"message" : "Image '<%= image["id"] %>' has been updated"
|
||||
}
|
||||
"""
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image with invalid id - hash
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
@<%= provider %>
|
||||
Scenario: Update <%= provider %> image with old bootstrap_template: '<%= image["bootstrap_template"] %>'
|
||||
When I send PUT '/v2.0/image/<%= image["id"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": {}
|
||||
}
|
||||
<%= @formatter.json(provider + '/image', {value: {"bootstrap_template" => image["bootstrap_template"]}}) %>
|
||||
"""
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
@ -415,28 +129,9 @@ Feature: Update images
|
||||
And response should be JSON object like:
|
||||
"""
|
||||
{
|
||||
"message" : "Image '<%= @config["openstack"]["image"] %>' has been updated"
|
||||
"message" : "Image '<%= image["id"] %>' has been updated"
|
||||
}
|
||||
"""
|
||||
|
||||
@ec2
|
||||
Scenario: Update ec2 image
|
||||
When I send PUT '/v2.0/image/<%= @config["ec2"]["image"] %>' query with JSON body
|
||||
"""
|
||||
{
|
||||
"provider": "ec2",
|
||||
"name": "test-ec2",
|
||||
"remote_user": "ec2-user",
|
||||
"bootstrap_template": null,
|
||||
"id": "<%= @config["ec2"]["image"] %>"
|
||||
}
|
||||
"""
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
And response should be JSON object like:
|
||||
"""
|
||||
{
|
||||
"message" : "Image '<%= @config["openstack"]["image"] %>' has been updated"
|
||||
}
|
||||
"""
|
||||
<% end #providers %>
|
||||
|
||||
|
||||
@ -1,42 +1,37 @@
|
||||
@image @project
|
||||
Feature: delete image
|
||||
|
||||
@openstack
|
||||
Scenario: Delete openstack image with user without privileges
|
||||
When I send DELETE '/v2.0/image/<%= @config["openstack"]["image"] %>' query with user without privileges
|
||||
<% providers = @formatter.get_fixture('providers/without_static') %>
|
||||
<% providers.each do |provider| %>
|
||||
<% image = @formatter.get_fixture(provider + '/image') %>
|
||||
@<%= provider %>
|
||||
Scenario: Delete <%= provider %> image with user without privileges
|
||||
When I send DELETE '/v2.0/image/<%= image["id"] %>' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@openstack
|
||||
Scenario: Delete openstack image
|
||||
When I send DELETE '/v2.0/image/<%= @config["openstack"]["image"] %>' query
|
||||
@<%= provider %>
|
||||
Scenario: Delete <%= provider %> image
|
||||
When I send DELETE '/v2.0/image/<%= image["id"] %>' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
And response should be JSON object like:
|
||||
"""
|
||||
{
|
||||
"message" : "Image '<%= @config["openstack"]["image"] %>' has been removed"
|
||||
"message" : "Image '<%= image["id"] %>' has been removed"
|
||||
}
|
||||
"""
|
||||
|
||||
@ec2
|
||||
Scenario: Delete ec2 image with user without privileges
|
||||
When I send DELETE '/v2.0/image/<%= @config["ec2"]["image"] %>' query with user without privileges
|
||||
Then response should be '401'
|
||||
@<%= provider %>
|
||||
Scenario: Delete <%= provider %> image with header 'Accept' value is not 'application/json'
|
||||
When I send DELETE '/v2.0/image/<%= image["id"] %>' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
@ec2
|
||||
Scenario: Delete ec2 image
|
||||
When I send DELETE '/v2.0/image/<%= @config["ec2"]["image"] %>' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
And response should be JSON object like:
|
||||
"""
|
||||
{
|
||||
"message" : "Image '<%= @config["ec2"]["image"] %>' has been removed"
|
||||
}
|
||||
"""
|
||||
<% end #providers %>
|
||||
|
||||
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|provider| "@#{provider}"} %>
|
||||
<%= providers.join(" ") %>
|
||||
Scenario: Delete unknown image
|
||||
When I send DELETE '/v2.0/image/foo' query
|
||||
Then response should be '404'
|
||||
|
||||
@ -1,16 +1,22 @@
|
||||
@user
|
||||
Feature: delete user
|
||||
|
||||
<% user_hash = @formatter.get_fixture('user/create') %>
|
||||
<% username = user_hash["username"] %>
|
||||
Scenario: delete user with user without privileges
|
||||
When I send DELETE '/v2.0/user/<%= @config["user"]["name"] %>' query with user without privileges
|
||||
When I send DELETE '/v2.0/user/<%= username %>' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
Scenario: delete unknown user
|
||||
When I send DELETE '/v2.0/user/unknown' query
|
||||
Then response should be '404'
|
||||
|
||||
Scenario: delete user with header 'Accept' value is not 'application/json'
|
||||
When I send DELETE '/v2.0/user/<%= username %>' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
Scenario: delete user
|
||||
When I send DELETE '/v2.0/user/<%= @config["user"]["name"] %>' query
|
||||
When I send DELETE '/v2.0/user/<%= username %>' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
|
||||
|
||||
@ -1,153 +1,58 @@
|
||||
@filter @image @project
|
||||
Feature: Filters
|
||||
|
||||
@openstack
|
||||
Scenario: Delete openstack image filter with user without privileges
|
||||
When I send DELETE '/v2.0/filter/openstack/image' query with user without privileges
|
||||
<% @formatter.get_fixture('providers/without_static').each do |provider| %>
|
||||
<% image = @formatter.get_fixture(provider + "/image")["id"] %>
|
||||
@<%= provider %>
|
||||
Scenario: Delete <%= provider %> image filter with user without privileges
|
||||
When I send DELETE '/v2.0/filter/<%= provider %>/image' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@openstack
|
||||
Scenario: Delete openstack image filter without header 'Content-Type'
|
||||
When I send DELETE '/v2.0/filter/openstack/image' query with JSON body without header 'Content-Type'
|
||||
@<%= provider %>
|
||||
Scenario: Delete images filter with header 'Accept' value not 'application/json'
|
||||
When I send DELETE '/v2.0/filter/<%= provider %>/image' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
@<%= provider %>
|
||||
Scenario: Delete <%= provider %> image filter without header 'Content-Type'
|
||||
When I send DELETE '/v2.0/filter/<%= provider %>/image' query with JSON body without header 'Content-Type'
|
||||
"""
|
||||
[
|
||||
"<%= @config["openstack"]["image"] %>"
|
||||
"<%= image %>"
|
||||
]
|
||||
"""
|
||||
Then response should be '415'
|
||||
|
||||
@openstack
|
||||
Scenario: Delete openstack image filter, invalid body: empty
|
||||
When I send DELETE '/v2.0/filter/openstack/image' query with JSON body
|
||||
<% ["", "{}", "[{}]", "[[]]", "[null]"].each do |body| %>
|
||||
@<%= provider %>
|
||||
Scenario: Delete <%= provider %> image filter, invalid body: empty
|
||||
When I send DELETE '/v2.0/filter/<%= provider %>/image' query with JSON body
|
||||
"""
|
||||
<%= body %>
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Delete openstack image filter, invalid body: hash
|
||||
When I send DELETE '/v2.0/filter/openstack/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"foo": "foo"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
<% end %>
|
||||
|
||||
@openstack
|
||||
Scenario: Delete openstack image filter, invalid body: element is hash
|
||||
When I send DELETE '/v2.0/filter/openstack/image' query with JSON body
|
||||
"""
|
||||
[{
|
||||
"foo": "foo"
|
||||
}]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Delete openstack image filter, invalid body: element is array
|
||||
When I send DELETE '/v2.0/filter/openstack/image' query with JSON body
|
||||
@<%= provider %>
|
||||
Scenario: Delete <%= provider %> image filter
|
||||
When I send DELETE '/v2.0/filter/<%= provider %>/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
[]
|
||||
]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Delete openstack image filter, invalid body: element is null
|
||||
When I send DELETE '/v2.0/filter/openstack/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
null
|
||||
]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@openstack
|
||||
Scenario: Delete openstack image filter
|
||||
When I send DELETE '/v2.0/filter/openstack/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
"<%= @config["openstack"]["image"] %>"
|
||||
"<%= image %>"
|
||||
]
|
||||
"""
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
And the object should contains key 'images' with array and array should not contains strings '<%= @config["openstack"]["image"] %>'
|
||||
And the object should contains key 'images' with array and array should not contains strings '<%= image %>'
|
||||
|
||||
@ec2
|
||||
Scenario: Delete ec2 image filter with user without privileges
|
||||
When I send DELETE '/v2.0/filter/ec2/image' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
@ec2
|
||||
Scenario: Delete ec2 image filter without header 'Content-Type'
|
||||
When I send DELETE '/v2.0/filter/ec2/image' query with JSON body without header 'Content-Type'
|
||||
"""
|
||||
[
|
||||
"<%= @config["ec2"]["image"] %>"
|
||||
]
|
||||
"""
|
||||
Then response should be '415'
|
||||
|
||||
@ec2
|
||||
Scenario: Delete ec2 image filter, invalid body: empty
|
||||
When I send DELETE '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Delete ec2 image filter, invalid body: hash
|
||||
When I send DELETE '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
{
|
||||
"foo": "foo"
|
||||
}
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Delete ec2 image filter, invalid body: element is hash
|
||||
When I send DELETE '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
[{
|
||||
"foo": "foo"
|
||||
}]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Delete ec2 image filter, invalid body: element is array
|
||||
When I send DELETE '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
[]
|
||||
]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Delete ec2 image filter, invalid body: element is null
|
||||
When I send DELETE '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
null
|
||||
]
|
||||
"""
|
||||
Then response should be '400'
|
||||
|
||||
@ec2
|
||||
Scenario: Delete ec2 image filter
|
||||
When I send DELETE '/v2.0/filter/ec2/image' query with JSON body
|
||||
"""
|
||||
[
|
||||
"<%= @config["ec2"]["image"] %>"
|
||||
]
|
||||
"""
|
||||
@<%= provider %>
|
||||
Scenario: Get new (after delete) <%= provider %> image filter and check value '<%= image %>'
|
||||
When I send GET '/v2.0/filter/<%= provider %>/images' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
And the object should contains key 'images' with array and array should not contains strings '<%= @config["ec2"]["image"] %>'
|
||||
And the JSON response should be an array
|
||||
And the array should not contains strings '<%= image %>'
|
||||
|
||||
<% end %>
|
||||
|
||||
@ -1,9 +1,18 @@
|
||||
@key
|
||||
<% providers = @formatter.get_fixture('providers/all').map{|p| "@#{p}"} %>
|
||||
@key <%= providers.join(" ") %>
|
||||
Feature: Delete key
|
||||
|
||||
<% key_name = @fixtures['key']['valid']['key_name'] %>
|
||||
<% key = @formatter.get_fixture('key/new') %>
|
||||
Scenario: DELETE key with header 'Accept' value is not 'application/json'
|
||||
When I send DELETE '/v2.0/key/<%= key["key_name"] %>' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
Scenario: Delete key without privileges
|
||||
When I send DELETE '/v2.0/key/<%= key["key_name"] %>' query with user without privileges
|
||||
Then response should be '401'
|
||||
|
||||
Scenario: Delete key
|
||||
When I send DELETE '/v2.0/key/<%= key_name %>' query
|
||||
When I send DELETE '/v2.0/key/<%= key["key_name"] %>' query
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
And the JSON response should be an object
|
||||
|
||||
33
devops-service/tests/templates/fixtures/ec2.yml
Normal file
33
devops-service/tests/templates/fixtures/ec2.yml
Normal file
@ -0,0 +1,33 @@
|
||||
flavor:
|
||||
id: &flavor_id "t1.micro"
|
||||
cores: 2
|
||||
disk: 0
|
||||
name: "Micro Instance"
|
||||
ram: 613
|
||||
image:
|
||||
id: &image_id "id"
|
||||
provider: "ec2"
|
||||
remote_user: "root"
|
||||
name: &image_name ""
|
||||
bootstrap_template: "omnibus"
|
||||
network:
|
||||
cidr: cidr
|
||||
vpcId: vpcId
|
||||
subnetId: subnetId
|
||||
name: subnetId
|
||||
zone: availabilityZone
|
||||
provider_image:
|
||||
id: *image_id
|
||||
name: *image_name
|
||||
status: available
|
||||
deploy_env:
|
||||
identifier: ec2_env
|
||||
provider: "ec2"
|
||||
run_list: []
|
||||
expires: null
|
||||
users: []
|
||||
flavor: *flavor_id
|
||||
image: *image_id
|
||||
subnets: []
|
||||
groups: []
|
||||
stack_template: null
|
||||
@ -1,34 +1,42 @@
|
||||
require 'json'
|
||||
require 'pp'
|
||||
|
||||
class FixtureFormatter
|
||||
|
||||
def initialize(fixtures)
|
||||
@fixtures = fixtures
|
||||
if ENV["DEBUG"]
|
||||
puts "Loaded fixtures:"
|
||||
pp @fixtures
|
||||
end
|
||||
end
|
||||
|
||||
def json(path, options={})
|
||||
result = nil
|
||||
begin
|
||||
result = JSON.pretty_generate(get_fixture(path))
|
||||
result = JSON.pretty_generate(get_fixture(path, options))
|
||||
rescue
|
||||
raise "Fixture '#{path}' is absent"
|
||||
end
|
||||
if options[:spaces]
|
||||
options[:spaces] = 4 unless options[:spaces]
|
||||
result = shift_to_right(result, options[:spaces])
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_fixture(path)
|
||||
def get_fixture(path, options={})
|
||||
keys = path.split('/')
|
||||
hash = @fixtures
|
||||
keys.each do |key|
|
||||
hash = hash[key]
|
||||
end
|
||||
hash = hash.clone
|
||||
hash.merge!(options[:value]) if options[:value]
|
||||
hash.delete(options[:without_field]) if options[:without_field]
|
||||
hash
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def shift_to_right(text, spaces_count)
|
||||
buffer = ''
|
||||
first_line = true
|
||||
|
||||
@ -1,20 +1,8 @@
|
||||
valid: &valid
|
||||
list_element:
|
||||
scope: "system"
|
||||
id: "devops"
|
||||
new: &valid
|
||||
file_name: test_file_name
|
||||
key_name: test_key_name
|
||||
content: test_content
|
||||
|
||||
invalid:
|
||||
base: &invalid_base
|
||||
<<: *valid
|
||||
blank_file_name:
|
||||
<<: *invalid_base
|
||||
file_name:
|
||||
blank_key_name:
|
||||
<<: *invalid_base
|
||||
key_name:
|
||||
blank_content:
|
||||
<<: *invalid_base
|
||||
content:
|
||||
scope:
|
||||
<<: *invalid_base
|
||||
scope: inalid_scope
|
||||
30
devops-service/tests/templates/fixtures/openstack.yml
Normal file
30
devops-service/tests/templates/fixtures/openstack.yml
Normal file
@ -0,0 +1,30 @@
|
||||
flavor:
|
||||
id: &flavor_id "flavor_id"
|
||||
v_cpus: "v_cpus"
|
||||
ram: "ram"
|
||||
disk: "disk"
|
||||
image:
|
||||
id: &image_id "da25f4b0-3183-4993-ac2b-4744e4ed77cb"
|
||||
provider: "openstack"
|
||||
remote_user: "centos"
|
||||
name: &image_name "CentOS-7-x86_64"
|
||||
bootstrap_template: null
|
||||
provider_image:
|
||||
id: *image_id
|
||||
name: *image_name
|
||||
status: ACTIVE
|
||||
network:
|
||||
cidr: cidr
|
||||
id: subnetId
|
||||
name: subnetId
|
||||
deploy_env:
|
||||
identifier: ec2_env
|
||||
provider: "openstack"
|
||||
run_list: []
|
||||
expires: null
|
||||
users: []
|
||||
flavor: *flavor_id
|
||||
image: *image_id
|
||||
subnets: []
|
||||
groups: []
|
||||
stack_template: null
|
||||
3
devops-service/tests/templates/fixtures/project.yml
Normal file
3
devops-service/tests/templates/fixtures/project.yml
Normal file
@ -0,0 +1,3 @@
|
||||
name: cucumber_project
|
||||
description: "Cucumber test project"
|
||||
|
||||
4
devops-service/tests/templates/fixtures/providers.yml
Normal file
4
devops-service/tests/templates/fixtures/providers.yml
Normal file
@ -0,0 +1,4 @@
|
||||
without_static:
|
||||
[openstack, ec2]
|
||||
all:
|
||||
[openstack, ec2, static]
|
||||
7
devops-service/tests/templates/fixtures/static.yml
Normal file
7
devops-service/tests/templates/fixtures/static.yml
Normal file
@ -0,0 +1,7 @@
|
||||
deploy_env:
|
||||
identifier: static_env
|
||||
provider: "static"
|
||||
run_list: []
|
||||
expires: null
|
||||
users: []
|
||||
|
||||
34
devops-service/tests/templates/fixtures/user.yml
Normal file
34
devops-service/tests/templates/fixtures/user.yml
Normal file
@ -0,0 +1,34 @@
|
||||
privileges: &privileges
|
||||
flavor: "rwx"
|
||||
group: "rwx"
|
||||
image: "rwx"
|
||||
project: "rwx"
|
||||
server: "rwx"
|
||||
key: "rwx"
|
||||
user: "rwx"
|
||||
filter: "rwx"
|
||||
network: "rwx"
|
||||
provider: "rwx"
|
||||
script: "rwx"
|
||||
templates: "rwx"
|
||||
stack: "rwx"
|
||||
stack_template: "rwx"
|
||||
|
||||
show: &valid_show
|
||||
email: "test@test.test"
|
||||
privileges: *privileges
|
||||
id: "test"
|
||||
|
||||
update: &valid_update
|
||||
email: cucumber_test@test.test
|
||||
password: test
|
||||
|
||||
create: &valid_create
|
||||
<<: *valid_update
|
||||
username: cucumber_test
|
||||
|
||||
privileges_values: ['', r, w, x, rw, rx, wx, rwx]
|
||||
|
||||
privileges_update:
|
||||
cmd: all
|
||||
privileges: r
|
||||
@ -0,0 +1,21 @@
|
||||
class PathScenariosGenerator
|
||||
|
||||
def generate_get_path_scenarios name, path
|
||||
%Q(
|
||||
Scenario: #{name}
|
||||
When I send GET '#{path}' query with JSON body
|
||||
Then response should be '200'
|
||||
And the Content-Type header should include 'application/json'
|
||||
#{yield}
|
||||
|
||||
Scenario: #{name} with header 'Accept' value is not 'application/json'
|
||||
When I send GET '#{path}' query with header 'Accept' value 'application/xml'
|
||||
Then response should be '406'
|
||||
|
||||
Scenario: #{name} without privileges
|
||||
When I send GET '#{path}' query with user without privileges
|
||||
Then response should be '401'
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user