This commit is contained in:
amartynov 2014-05-23 17:36:16 +04:00
parent 67fe28252b
commit adda39e046
7 changed files with 156 additions and 21 deletions

View File

@ -40,6 +40,12 @@ class Server < Handler
when "unpause" when "unpause"
self.options = @options_parser.unpause_options self.options = @options_parser.unpause_options
unpause_handler @options_parser.args unpause_handler @options_parser.args
when "reserve"
self.options = @options_parser.reserve_options
reserve_handler @options_parser.args
when "unreserve"
self.options = @options_parser.unreserve_options
unreserve_handler @options_parser.args
when "add" when "add"
self.options = @options_parser.add_options self.options = @options_parser.add_options
add_static_handler @options_parser.args add_static_handler @options_parser.args
@ -152,7 +158,7 @@ class Server < Handler
@options_parser.invalid_pause_command @options_parser.invalid_pause_command
abort(r) abort(r)
end end
post "/server/#{args[2]}/pause" post "/server/#{args[2]}/pause", options
end end
def unpause_handler args def unpause_handler args
@ -161,7 +167,25 @@ class Server < Handler
@options_parser.invalid_unpause_command @options_parser.invalid_unpause_command
abort(r) abort(r)
end end
post "/server/#{args[2]}/unpause" post "/server/#{args[2]}/unpause", options
end
def reserve_handler args
r = inspect_parameters @options_parser.reserve_params, args[2]
unless r.nil?
@options_parser.invalid_reserve_command
abort(r)
end
post "/server/#{args[2]}/reserve", options
end
def unreserve_handler args
r = inspect_parameters @options_parser.unreserve_params, args[2]
unless r.nil?
@options_parser.invalid_unreserve_command
abort(r)
end
post "/server/#{args[2]}/unreserve", options
end end
end end

View File

@ -2,7 +2,7 @@ require "devops-client/options/common_options"
class ServerOptions < CommonOptions class ServerOptions < CommonOptions
commands :add, :bootstrap, :create, :delete, :list, :pause, :show, :unpause # :sync, commands :add, :bootstrap, :create, :delete, :list, :pause, :reserve, :show, :unpause, :unreserve # :sync,
def initialize args, def_options def initialize args, def_options
super(args, def_options) super(args, def_options)
@ -15,6 +15,8 @@ class ServerOptions < CommonOptions
self.show_params = node_params self.show_params = node_params
self.pause_params = node_params self.pause_params = node_params
self.unpause_params = node_params self.unpause_params = node_params
self.reserve_params = node_params
self.unreserve_params = node_params
self.bootstrap_params = ["INSTANCE_ID"] self.bootstrap_params = ["INSTANCE_ID"]
self.add_params = ["PROJECT_ID", "DEPLOY_ENV", "IP", "SSH_USER", "KEY_ID"] self.add_params = ["PROJECT_ID", "DEPLOY_ENV", "IP", "SSH_USER", "KEY_ID"]
end end
@ -34,6 +36,46 @@ class ServerOptions < CommonOptions
end end
end end
def pause_options
options do |opts, options|
opts.banner << self.delete_banner
options[:key] = "node"
opts.on('--instance', "Pause server by instance id") do
options[:key] = "instance"
end
end
end
def unpause_options
options do |opts, options|
opts.banner << self.delete_banner
options[:key] = "node"
opts.on('--instance', "Unpause server by instance id") do
options[:key] = "instance"
end
end
end
def reserve_options
options do |opts, options|
opts.banner << self.delete_banner
options[:key] = "node"
opts.on('--instance', "Reserve server by instance id") do
options[:key] = "instance"
end
end
end
def unreserve_options
options do |opts, options|
opts.banner << self.delete_banner
options[:key] = "node"
opts.on('--instance', "Unreserve server by instance id") do
options[:key] = "instance"
end
end
end
def create_options def create_options
options do |opts, options| options do |opts, options|
opts.banner << self.create_banner opts.banner << self.create_banner

View File

@ -1,3 +1,3 @@
module DevopsClient module DevopsClient
VERSION = "2.1.29" VERSION = "2.1.30"
end end

View File

@ -3,7 +3,7 @@ require "db/mongo/models/mongo_model"
class Server < MongoModel class Server < MongoModel
attr_accessor :provider, :chef_node_name, :id, :remote_user, :project, :deploy_env, :private_ip, :public_ip, :created_at, :without_bootstrap, :created_by attr_accessor :provider, :chef_node_name, :id, :remote_user, :project, :deploy_env, :private_ip, :public_ip, :created_at, :without_bootstrap, :created_by, :reserved_by
attr_accessor :options, :static, :key attr_accessor :options, :static, :key
types :id => {:type => String, :empty => false}, types :id => {:type => String, :empty => false},
@ -15,7 +15,8 @@ class Server < MongoModel
:public_ip => {:type => String, :empty => true, :nil => true}, :public_ip => {:type => String, :empty => true, :nil => true},
:key => {:type => String, :empty => false}, :key => {:type => String, :empty => false},
:created_by => {:type => String, :empty => false}, :created_by => {:type => String, :empty => false},
:chef_node_name => {:type => String, :empty => true} :chef_node_name => {:type => String, :empty => true},
:reserved_by => {:type => String, :empty => true}
def initialize def initialize
self.static = false self.static = false
@ -38,7 +39,8 @@ class Server < MongoModel
"created_at" => self.created_at, "created_at" => self.created_at,
"created_by" => self.created_by, "created_by" => self.created_by,
"static" => self.static, "static" => self.static,
"key" => self.key "key" => self.key,
"reserved_by" => self.reserved_by
} }
end end
@ -63,6 +65,7 @@ class Server < MongoModel
server.created_by = s["created_by"] server.created_by = s["created_by"]
server.static = s["static"] || false server.static = s["static"] || false
server.key = s["key"] server.key = s["key"]
server.reserved_by = s["reserved_by"]
server server
end end

View File

@ -19,7 +19,7 @@ module Version2_0
statistic statistic
end end
# Run chef-client on some instances # Run chef-client on reserved server
# #
# * *Request* # * *Request*
# - method : POST # - method : POST
@ -40,7 +40,8 @@ module Version2_0
tags = check_array(r["tags"], "Parameter 'tags' should be an array of strings", String, true) || [] tags = check_array(r["tags"], "Parameter 'tags' should be an array of strings", String, true) || []
servers = BaseRoutes.mongo.servers_by_names(names) servers = BaseRoutes.mongo.servers_by_names(names)
halt(404, "No servers found for names '#{names.join("', '")}'") if servers.empty? servers.delete_if{|s| s.reserved_by.nil?}
halt(404, "No reserved servers found for names '#{names.join("', '")}'") if servers.empty?
keys = {} keys = {}
servers.sort_by!{|s| names.index(s.chef_node_name)} servers.sort_by!{|s| names.index(s.chef_node_name)}
stream() do |out| stream() do |out|

View File

@ -349,7 +349,7 @@ module Version2_0
create_response(info) create_response(info)
end end
# Run chef-client on project servers # Run chef-client on reserved project servers
# #
# * *Request* # * *Request*
# - method : POST # - method : POST
@ -372,6 +372,7 @@ module Version2_0
check_array(obj["servers"], "Parameter 'servers' should be a not empty array of strings", String, true) check_array(obj["servers"], "Parameter 'servers' should be a not empty array of strings", String, true)
project = BaseRoutes.mongo.project(params[:id]) project = BaseRoutes.mongo.project(params[:id])
servers = BaseRoutes.mongo.servers(params[:id], obj["deploy_env"]) servers = BaseRoutes.mongo.servers(params[:id], obj["deploy_env"])
servers.delete_if{|s| s.reserved_by.nil?}
unless obj["servers"].nil? unless obj["servers"].nil?
logger.debug "Servers in params: #{obj["servers"].inspect}\nServers: #{servers.map{|s| s.chef_node_name}.inspect}" logger.debug "Servers in params: #{obj["servers"].inspect}\nServers: #{servers.map{|s| s.chef_node_name}.inspect}"
servers.select!{|ps| obj["servers"].include?(ps.chef_node_name)} servers.select!{|ps| obj["servers"].include?(ps.chef_node_name)}
@ -379,7 +380,7 @@ module Version2_0
keys = {} keys = {}
stream() do |out| stream() do |out|
begin begin
out << (servers.empty? ? "No servers to deploy\n" : "Deploy servers: '#{servers.map{|s| s.chef_node_name}.join("', '")}'\n") out << (servers.empty? ? "No reserved servers to deploy\n" : "Deploy servers: '#{servers.map{|s| s.chef_node_name}.join("', '")}'\n")
status = [] status = []
servers.each do |s| servers.each do |s|

View File

@ -47,9 +47,11 @@ module Version2_0
check_privileges("server") check_privileges("server")
end end
before %r{\A/server/[\w]+/(un)?pause\z} do before %r{\A/server/[\w]+/(pause|unpouse|reserve|unreserve)\z} do
check_headers :accept, :content_type check_headers :accept, :content_type
check_privileges("server", "w") check_privileges("server", "w")
body = create_object_from_json_body(Hash, true)
@key = (body.nil? ? nil : body["key"])
end end
before "/servers/:provider" do before "/servers/:provider" do
@ -146,6 +148,8 @@ module Version2_0
# - method : GET # - method : GET
# - headers : # - headers :
# - Accept: application/json # - Accept: application/json
# - parameters:
# key=instance -> search server by instance_id rather then chef_node_name
# #
# * *Returns* : # * *Returns* :
# [ # [
@ -154,7 +158,7 @@ module Version2_0
# } # }
# ] # ]
get "/server/:name" do get "/server/:name" do
json BaseRoutes.mongo.server_by_chef_node_name(params[:name]) json get_server(params[:name], params[:key]).to_hash
end end
# Delete devops server # Delete devops server
@ -164,18 +168,17 @@ module Version2_0
# - headers : # - headers :
# - Accept: application/json # - Accept: application/json
# - Content-Type: application/json # - Content-Type: application/json
# - body # - body :
# { # {
# "key": "instance" -> if key=instance, then :name - instance id, if key=null, then name - node name # "key": "instance", -> search server by instance_id rather then chef_node_name
# } # }
# #
# * *Returns* : # * *Returns* :
# 200 - Deleted # 200 - Deleted
delete "/server/:id" do delete "/server/:id" do
body = create_object_from_json_body(Hash, true) body = create_object_from_json_body(Hash, true)
key = (body.nil? ? nil : body["key"]) key = (body.nil? ? nil : body["key"])
id = params[:id] s = get_server(params[:id], key)
s = (key == "instance" ? BaseRoutes.mongo.server_by_instance_id(id) : BaseRoutes.mongo.server_by_chef_node_name(id))
### Authorization ### Authorization
BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER'] BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER']
info, r = delete_server(s, BaseRoutes.mongo, logger) info, r = delete_server(s, BaseRoutes.mongo, logger)
@ -271,11 +274,16 @@ module Version2_0
# - method : POST # - method : POST
# - headers : # - headers :
# - Accept: application/json # - Accept: application/json
# - Content-Type: application/json
# - body :
# {
# "key": "instance", -> search server by instance_id rather then chef_node_name
# }
# #
# * *Returns* : # * *Returns* :
# 200 - Paused # 200 - Paused
post "/server/:node_name/pause" do post "/server/:node_name/pause" do
s = BaseRoutes.mongo.server_by_chef_node_name params[:node_name] s = get_server(params[:node_name], @key)
## Authorization ## Authorization
BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER'] BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER']
provider = ::Version2_0::Provider::ProviderFactory.get(s.provider) provider = ::Version2_0::Provider::ProviderFactory.get(s.provider)
@ -293,11 +301,16 @@ module Version2_0
# - method : POST # - method : POST
# - headers : # - headers :
# - Accept: application/json # - Accept: application/json
# - Content-Type: application/json
# - body :
# {
# "key": "instance", -> search server by instance_id rather then chef_node_name
# }
# #
# * *Returns* : # * *Returns* :
# 200 - Unpaused # 200 - Unpaused
post "/server/:node_name/unpause" do post "/server/:node_name/unpause" do
s = BaseRoutes.mongo.server_by_chef_node_name params[:node_name] s = get_server(params[:node_name], @key)
## Authorization ## Authorization
BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER'] BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER']
provider = ::Version2_0::Provider::ProviderFactory.get(s.provider) provider = ::Version2_0::Provider::ProviderFactory.get(s.provider)
@ -309,6 +322,53 @@ module Version2_0
end end
end end
# Reserve 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 - Reserved
post "/server/:node_name/reserve" do
s = get_server(params[:node_name], params[:key])
user = request.env['REMOTE_USER']
BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, user
halt_response(400, "Server '#{params[:node_name]}' already reserved") unless s.reserved_by.nil?
s.reserved_by = user
BaseRoutes.mongo.server_update(s)
create_response("Server '#{params[:node_name]}' has been reserved")
end
# Unreserve 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 - Unreserved
post "/server/:node_name/unreserve" do
s = get_server(params[:node_name], params[:key])
BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER']
halt_response(400, "Server '#{params[:node_name]}' is not reserved") if s.reserved_by.nil?
s.reserved_by = nil
BaseRoutes.mongo.server_update(s)
create_response("Server '#{params[:node_name]}' has been unreserved")
end
# Bootstrap devops server # Bootstrap devops server
# #
# * *Request* # * *Request*
@ -416,6 +476,10 @@ module Version2_0
end end
private private
def get_server id, key
key == "instance" ? BaseRoutes.mongo.server_by_instance_id(id) : BaseRoutes.mongo.server_by_chef_node_name(id)
end
def roll_back s, provider def roll_back s, provider
str = "" str = ""
unless s.id.nil? unless s.id.nil?