add possibility to add and bootstrap list of servers at once

This commit is contained in:
Anton Chuchkalov 2016-02-16 10:01:43 +03:00
parent edc906dc24
commit 27f777d924
5 changed files with 152 additions and 23 deletions

View File

@ -39,6 +39,8 @@ class Server < Handler
unreserve_handler unreserve_handler
when :add when :add
add_static_handler add_static_handler
when :add_and_bootstrap_list
add_and_bootstrap_list_handler
end end
end end
@ -93,7 +95,7 @@ class Server < Handler
end end
end end
end end
"" nil
end end
def show_handler def show_handler
@ -123,7 +125,7 @@ class Server < Handler
post_chunk "/server/bootstrap", q post_chunk "/server/bootstrap", q
end end
def add_static_handler # add <project> <env> <private_ip> <ssh_username> --public-ip <public_ip> -k <keyname> def add_static_handler # add <project> <env> <private_ip> <ssh_username> <keyname> --public-ip <public_ip>
r = inspect_parameters @options_parser.add_params, @args[2], @args[3], @args[4], @args[5], @args[6] r = inspect_parameters @options_parser.add_params, @args[2], @args[3], @args[4], @args[5], @args[6]
unless r.nil? unless r.nil?
@options_parser.invalid_add_command @options_parser.invalid_add_command
@ -140,6 +142,24 @@ class Server < Handler
post "/server/add", q post "/server/add", q
end end
def add_and_bootstrap_list_handler
project, env, user, key, ips_file_path = @args[2..6]
r = inspect_parameters @options_parser.add_and_bootstrap_list_params, project, env, user, key, ips_file_path
unless r.nil?
@options_parser.invalid_add_and_bootstrap_list_command
abort(r)
end
q = {
project: project,
deploy_env: env,
remote_user: user,
key: key,
ips_with_names: get_file_contents(ips_file_path)
}
q[:public_ip] = options[:public_ip] if options[:public_ip]
post "/server/add_and_bootstrap_servers", q
end
def pause_handler def pause_handler
r = inspect_parameters @options_parser.pause_params, @args[2] r = inspect_parameters @options_parser.pause_params, @args[2]
unless r.nil? unless r.nil?

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, :reserve, :show, :unpause, :unreserve # :sync, commands :add, :bootstrap, :create, :delete, :list, :pause, :reserve, :show, :unpause, :unreserve, :add_and_bootstrap_list
def initialize args, def_options def initialize args, def_options
super(args, def_options) super(args, def_options)
@ -19,6 +19,7 @@ class ServerOptions < CommonOptions
self.unreserve_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"]
self.add_and_bootstrap_list_params = ["PROJECT_ID", "DEPLOY_ENV", "SSH_USER", "KEY_ID", "IPS_FILE"]
end end
def delete_options def delete_options
@ -157,6 +158,16 @@ class ServerOptions < CommonOptions
end end
end end
def add_and_bootstrap_list_options
options do |parser, options|
parser.banner << self.add_and_bootstrap_list_banner
parser.separator ''
parser.separator "\tIPS_FILE is path to a file with list of ip:node_name pairs; example of such file:"
parser.separator "\type127.0.0.1:node1"
parser.separator "\type127.0.0.2:node2"
end
end
def delete_banner def delete_banner
self.banner_header + " delete NODE_NAME [NODE_NAME ...]\n" self.banner_header + " delete NODE_NAME [NODE_NAME ...]\n"
end end

View File

@ -199,7 +199,6 @@ module Devops
owner: parser.current_user owner: parser.current_user
) )
sleep 1
[jid] [jid]
end end
@ -236,28 +235,27 @@ module Devops
end end
def add_server def add_server
body = parser.add_server project, deploy_env, server_attrs = parser.add_server
project = body["project"] Devops::Db.connector.check_project_auth project, deploy_env, parser.current_user
deploy_env = body["deploy_env"]
p = Devops::Db.connector.check_project_auth project, deploy_env, parser.current_user
d = p.deploy_env(deploy_env) add_static_server(server_attrs)
cert = Devops::Db.connector.key(body["key"])
provider = ::Provider::ProviderFactory.get("static")
s = Devops::Model::Server.new
s.provider = provider.name
s.project = project
s.deploy_env = deploy_env
s.remote_user = body["remote_user"]
s.private_ip = body["private_ip"]
s.public_ip = body["public_ip"]
s.id = "static_#{cert.id}-#{Time.now.to_i}"
s.key = cert.id
Devops::Db.connector.server_insert s
"Server '#{s.id}' has been added" "Server '#{s.id}' has been added"
end end
# returns jobs ids
def add_and_bootstrap_servers
body, servers_attrs = parser.add_and_bootstrap_servers
Devops::Db.connector.check_project_auth body['project'], body['deploy_env'], parser.current_user
servers_attrs.map do |attrs|
server = add_static_server(attrs)
Worker.start_async(BootstrapWorker,
server_attrs: server.to_mongo_hash,
bootstrap_template: body['bootstrap_template'],
owner: parser.current_user
)
end
end
def set_tags node_name def set_tags node_name
tags = parser.tags tags = parser.tags
prepare_tags do |id, provider| prepare_tags do |id, provider|
@ -305,6 +303,33 @@ module Devops
private private
# Security checks should be already done here.
# @attrs should be a hash with:
# :project
# :deploy_env
# :key
# :remote_user
# :private_ip
# :public_ip
# :chef_node_name
# :run_list
def add_static_server(attrs)
server = Devops::Model::Server.new(
'id' => "static_#{attrs[:key]}-#{attrs[:chef_node_name]}-#{Time.now.to_i}",
'provider' => ::Provider::ProviderFactory.get('static').name,
'project' => attrs[:project],
'deploy_env' => attrs[:deploy_env],
'remote_user' => attrs[:remote_user],
'private_ip' => attrs[:private_ip],
'public_ip' => attrs[:public_ip],
'key' => attrs[:key],
'chef_node_name' => attrs[:chef_node_name],
'run_list' => attrs[:run_list]
)
Devops::Db.connector.server_insert(server)
server
end
def check_if_server_attrs_are_valid(body, user) def check_if_server_attrs_are_valid(body, user)
key_name = body["key"] key_name = body["key"]
Devops::Db.connector.key(key_name) unless key_name.nil? Devops::Db.connector.key(key_name) unless key_name.nil?

View File

@ -60,7 +60,41 @@ module Devops
public_ip = check_string(@body["public_ip"], "Parameter 'public_ip' should be a not empty string", true) public_ip = check_string(@body["public_ip"], "Parameter 'public_ip' should be a not empty string", true)
rl = check_array(@body["run_list"], "Parameter 'run_list' should be a not empty array of string", String, true, true) rl = check_array(@body["run_list"], "Parameter 'run_list' should be a not empty array of string", String, true, true)
Validators::Helpers::RunList.new(rl).validate! unless rl.nil? Validators::Helpers::RunList.new(rl).validate! unless rl.nil?
@body server_attrs = {
project: project,
deploy_env: deploy_env,
key: key,
remote_user: remote_user,
private_ip: private_ip,
public_ip: public_ip,
run_list: rl
}
[project, deploy_env, server_attrs]
end
def add_and_bootstrap_servers
@body ||= create_object_from_json_body
project = check_string(@body["project"], "Parameter 'project' must be a not empty string")
deploy_env = check_string(@body["deploy_env"], "Parameter 'deploy_env' must be a not empty string")
key = check_string(@body["key"], "Parameter 'key' must be a not empty string")
remote_user = check_string(@body["remote_user"], "Parameter 'remote_user' must be a not empty string")
rl = check_array(@body["run_list"], "Parameter 'run_list' should be a not empty array of string", String, true, true)
check_string(@body["bootstrap_template"], "Parameter 'bootstrap_template' should be a not empty string", true)
Validators::Helpers::RunList.new(rl).validate! unless rl.nil?
ips_with_names = parse_list_of_ips_with_names(@body['ips_with_names'])
servers_attrs = ips_with_names.map do |ip, chef_node_name|
{
project: project,
deploy_env: deploy_env,
key: key,
remote_user: remote_user,
private_ip: ip,
chef_node_name: chef_node_name,
run_list: rl
}
end
[@body, servers_attrs]
end end
def tags def tags
@ -75,6 +109,17 @@ module Devops
rl rl
end end
private
def parse_list_of_ips_with_names(text)
hash = {}
text.each_line do |line|
ip, name = line.split(':').map(&:strip)
hash[ip] = name
end
hash
end
end end
end end
end end

View File

@ -376,6 +376,34 @@ module Devops
create_response(info) create_response(info)
end end
# Add list of external servers to devops and bootstrap them
#
# * *Request*
# - method : POST
# - headers :
# - Accept: application/json
# - Content-Type: application/json
# - body :
# {
# "project": "project name", -> required
# "deploy_env": "env", -> required
# "key": "ssh key", -> required
# "remote_user": "ssh user", -> required
# "ips_with_names": multiline string like, required
# 127.0.0.1:node1
# 127.0.0.2:node2
# "private_ip": "ip", -> required
# "public_ip": "ip"
# }
#
# * *Returns* :
# ["report1", "report2"]
app.post_with_headers "/server/add_and_bootstrap_servers", :headers => [:accept, :content_type] do
check_privileges("server", "w")
json Devops::API2_0::Handler::Server.new(request).add_and_bootstrap_servers()
end
hash = {} hash = {}
# Add instance tags # Add instance tags
# #