fluke/devops-service/app/api2/handlers/server.rb

333 lines
12 KiB
Ruby
Raw Normal View History

2014-12-22 14:22:04 +03:00
require "uri"
require "commands/status"
require "commands/bootstrap_templates"
2015-08-12 11:37:17 +03:00
require "lib/executors/server_executor"
2014-12-22 14:22:04 +03:00
require "providers/provider_factory"
require "db/mongo/models/server"
require "workers/create_server_worker"
require "workers/bootstrap_worker"
2015-07-30 15:37:43 +03:00
require "app/api2/parsers/server"
require_relative "request_handler"
2014-12-22 14:22:04 +03:00
module Devops
2015-07-17 20:22:29 +03:00
module API2_0
2014-12-22 14:22:04 +03:00
module Handler
2015-07-30 15:37:43 +03:00
class Server < RequestHandler
set_parser Devops::API2_0::Parser::ServerParser
2014-12-22 14:22:04 +03:00
extend StatusCommands
extend BootstrapTemplatesCommands
#scheduler = Rufus::Scheduler.new
2014-12-22 14:22:04 +03:00
2015-07-30 15:37:43 +03:00
def servers
fields, reserved = parser.servers
2015-08-05 17:30:42 +03:00
Devops::Db.connector.servers(nil, nil, nil, reserved, fields).map {|s| s.to_hash}
2014-12-22 14:22:04 +03:00
end
2015-07-17 20:22:29 +03:00
def chef_servers
2015-08-11 19:47:54 +03:00
KnifeFactory.instance.chef_node_list
2014-12-22 14:22:04 +03:00
end
2015-07-17 20:22:29 +03:00
def provider_servers provider
2015-10-28 14:16:56 +03:00
provider_servers_with_account provider, nil
end
def provider_servers_with_account provider, account
::Provider::ProviderFactory.get(provider, account).servers
2014-12-22 14:22:04 +03:00
end
2015-07-27 15:40:10 +03:00
def server id
2015-08-05 17:30:42 +03:00
get_server_by_key(id, parser.server)
2014-12-22 14:22:04 +03:00
end
2015-07-30 15:37:43 +03:00
def delete id
s = get_server_by_key(id, parser.instance_key)
2015-07-27 15:40:10 +03:00
### Authorization
2015-07-30 15:37:43 +03:00
Devops::Db.connector.check_project_auth s.project, s.deploy_env, parser.current_user
2015-08-12 17:14:01 +03:00
Devops::Executor::ServerExecutor.new(s, "").delete_server
2014-12-22 14:22:04 +03:00
end
2015-08-12 11:37:17 +03:00
def create_server_stream out
2015-07-27 15:40:10 +03:00
status = []
2015-08-05 14:05:14 +03:00
prepare_create_server do |project, env, user, body|
2015-08-12 11:37:17 +03:00
e = Devops::Executor::ServerExecutor.new(nil, out)
e.project = project
e.deploy_env = env
body["created_by"] = user
res = e.create_server(body)
2015-07-27 15:40:10 +03:00
status.push res
end
status
2014-12-22 14:22:04 +03:00
end
2015-07-30 15:37:43 +03:00
def create_server
body = parser.create
user = parser.current_user
2015-07-27 15:40:10 +03:00
2015-09-01 16:54:21 +03:00
check_if_server_attrs_are_valid(body, user)
2015-11-03 12:05:07 +03:00
jid = Worker.start_async(CreateServerWorker,
2015-09-01 16:54:21 +03:00
server_attrs: body,
owner: user
)
2015-11-03 12:05:07 +03:00
[jid]
2014-12-22 14:22:04 +03:00
end
2015-11-02 13:09:53 +03:00
def deploy node_name
call_deploy(node_name) do |options|
[ Worker.start_async(DeployWorker, @request, options) ]
end
end
def deploy_stream node_name, out
call_deploy(node_name) do |options|
Worker.start_sync(DeployWorker, @request, options, out)
end
rescue RecordNotFound => e
out << e.message
-10
end
def call_deploy node_name
body = parser.deploy
names = body["names"]
tags = body["tags"] || []
run_list = body["run_list"]
dir = DevopsConfig.config[:report_dir_v2]
owner = parser.current_user
s = Server.get_server_by_key(node_name, parser.instance_key)
project = Devops::Db.connector.check_project_auth s.project, s.deploy_env, owner
deploy_info = create_deploy_info(s, project, body["build_number"])
deploy_info["run_list"] = run_list if run_list
yield({
server_attrs: s.to_hash,
owner: owner,
tags: tags,
deploy_info: deploy_info
})
end
2015-07-30 15:37:43 +03:00
def pause_server node_name
2015-11-09 18:57:22 +03:00
s = get_server_by_key(node_name, parser.instance_key)
2015-07-27 15:40:10 +03:00
## Authorization
2015-07-30 15:37:43 +03:00
Devops::Db.connector.check_project_auth s.project, s.deploy_env, parser.current_user
2015-08-14 13:28:03 +03:00
provider = s.provider_instance
2015-07-27 15:40:10 +03:00
r = provider.pause_server s
if r.nil?
2015-11-09 18:57:22 +03:00
set_last_operation_type_and_save(s, Devops::Model::Server::OperationType::PAUSE)
2015-07-27 15:40:10 +03:00
"Server with instance ID '#{s.id}' and node name '#{node_name}' is paused"
else
raise ConflictException.new("Server with instance ID '#{s.id}' and node name '#{node_name}' can not be paused, It in state '#{r}'", 409)
end
2014-12-22 14:22:04 +03:00
end
2015-07-30 15:37:43 +03:00
def unpause_server node_name
2015-11-09 18:57:22 +03:00
s = get_server_by_key(node_name, parser.instance_key)
2015-07-27 15:40:10 +03:00
## Authorization
2015-07-30 15:37:43 +03:00
Devops::Db.connector.check_project_auth s.project, s.deploy_env, parser.current_user
2015-08-14 13:28:03 +03:00
provider = s.provider_instance
2015-07-27 15:40:10 +03:00
r = provider.unpause_server s
if r.nil?
2015-11-09 18:57:22 +03:00
set_last_operation_type_and_save(s, Devops::Model::Server::OperationType::UNPAUSE)
2015-07-27 15:40:10 +03:00
"Server with instance ID '#{s.id}' and node name '#{node_name}' is unpaused"
else
raise ConflictException.new("Server with instance ID '#{s.id}' and node name '#{node_name}' can not be unpaused, It in state '#{r}'")
end
end
2015-07-30 15:37:43 +03:00
def reserve_server node_name
s = get_server_by_key(node_name, parser.instance_key)
user = parser.current_user
Devops::Db.connector.check_project_auth s.project, s.deploy_env, user
2015-07-27 15:40:10 +03:00
raise ConflictException.new("Server '#{node_name}' already reserved") unless s.reserved_by.nil?
s.reserved_by = user
2015-11-09 18:57:22 +03:00
set_last_operation_type_and_save(s, Devops::Model::Server::OperationType::RESERVE)
2015-07-27 15:40:10 +03:00
end
2015-07-30 15:37:43 +03:00
def unreserve_server node_name
s = get_server_by_key(node_name, parser.instance_key)
Devops::Db.connector.check_project_auth s.project, s.deploy_env, parser.current_user
2015-07-27 15:40:10 +03:00
raise ConflictException.new("Server '#{node_name}' is not reserved") if s.reserved_by.nil?
s.reserved_by = nil
2015-11-09 18:57:22 +03:00
set_last_operation_type_and_save(s, Devops::Model::Server::OperationType::UNRESERVE)
2014-12-22 14:22:04 +03:00
end
# TODO: check bootstrap template name
2015-07-30 15:37:43 +03:00
def bootstrap_server_stream out
2015-10-23 14:54:56 +03:00
options = prepare_bootstrap_server
2015-11-02 11:43:57 +03:00
s = options.delete(:server)
2015-07-27 15:40:10 +03:00
status = []
cert = Devops::Db.connector.key s.key
2015-08-10 13:17:04 +03:00
DevopsLogger.logger.debug "Bootstrap certificate path: #{cert.path}"
#bootstrap s, out, cert.path, logger
2015-10-23 14:54:56 +03:00
options[:cert_path] = cert.path
executor = Devops::Executor::ServerExecutor.new(s, out)
r = executor.two_phase_bootstrap(options)
2015-07-27 15:40:10 +03:00
str = nil
r = if check_server(s)
Devops::Db.connector.server_set_chef_node_name s
str = "Server with id '#{s.id}' is bootstraped"
2015-08-10 13:17:04 +03:00
DevopsLogger.logger.info str
2015-07-27 15:40:10 +03:00
0
else
str = "Server with id '#{s.id}' is not bootstraped"
2015-08-10 13:17:04 +03:00
DevopsLogger.logger.warn str
2015-07-27 15:40:10 +03:00
1
end
status.push r
out << str
out << "\n"
status
end
2015-07-30 15:37:43 +03:00
def bootstrap_server
2015-09-02 12:41:29 +03:00
server, rl, bootstrap_template = prepare_bootstrap_server
2015-10-23 14:54:56 +03:00
2015-11-03 12:05:07 +03:00
jid = Worker.start_async(BootstrapWorker,
2015-09-02 12:41:29 +03:00
server_attrs: server.to_mongo_hash,
bootstrap_template: bootstrap_template,
owner: parser.current_user
)
2015-07-27 15:40:10 +03:00
sleep 1
2015-11-03 12:05:07 +03:00
[jid]
2014-12-22 14:22:04 +03:00
end
2015-07-30 15:37:43 +03:00
def prepare_bootstrap_server
body = parser.bootstrap
2015-07-27 15:40:10 +03:00
id = body["instance_id"]
name = body["name"]
2015-08-10 13:01:34 +03:00
rl = body["run_list"]
t = body["bootstrap_template"]
2015-07-27 15:40:10 +03:00
s = Devops::Db.connector.server_by_instance_id(id)
2015-10-23 14:54:56 +03:00
res = {server: s}
2015-07-27 15:40:10 +03:00
2015-07-30 15:37:43 +03:00
p = Devops::Db.connector.check_project_auth s.project, s.deploy_env, parser.current_user
2015-08-10 13:01:34 +03:00
d = p.deploy_env(s.deploy_env)
2015-07-27 15:40:10 +03:00
2015-08-14 13:28:03 +03:00
provider = s.provider_instance
2015-07-27 15:40:10 +03:00
2015-08-14 13:28:03 +03:00
check_chef_node_name(name, provider, KnifeFactory.instance) unless name.nil?
2015-07-27 15:40:10 +03:00
unless t.nil?
templates = get_templates
halt_response("Invalid bootstrap template '#{t}', available values: #{templates.join(", ")}", 400) unless templates.include?(t)
2015-10-23 17:14:52 +03:00
res[:bootstrap_template] = t
2015-07-27 15:40:10 +03:00
end
s.chef_node_name = name || provider.create_default_chef_node_name(s)
2015-10-23 14:54:56 +03:00
res[:run_list] = rl || d.run_list
return res
2015-07-27 15:40:10 +03:00
end
2015-10-22 13:56:16 +03:00
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
2015-07-30 15:37:43 +03:00
def add_server
body = parser.add_server
2015-07-27 15:40:10 +03:00
project = body["project"]
deploy_env = body["deploy_env"]
2015-07-30 15:37:43 +03:00
p = Devops::Db.connector.check_project_auth project, deploy_env, parser.current_user
2015-07-27 15:40:10 +03:00
d = p.deploy_env(deploy_env)
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"
2014-12-22 14:22:04 +03:00
end
2015-08-03 18:01:50 +03:00
def set_tags node_name
2015-09-15 17:14:26 +03:00
tags = parser.tags
2015-08-03 18:01:50 +03:00
prepare_tags do |id, provider|
2015-09-15 17:14:26 +03:00
provider.set_tags id, tags
2015-08-03 18:01:50 +03:00
end
end
def unset_tags node_name
2015-09-15 17:14:26 +03:00
tags = parser.tags
2015-08-03 18:01:50 +03:00
prepare_tags do |id, provider|
2015-09-15 17:14:26 +03:00
provider.unset_tags id, tags
2015-08-03 18:01:50 +03:00
end
end
def prepare_tags node_name
s = get_server_by_key(node_name, parser.instance_key)
2015-08-14 13:28:03 +03:00
Devops::Db.connector.check_project_auth s.project, s.deploy_env, parser.current_user
2015-08-03 18:01:50 +03:00
provider = ::Provider::ProviderFactory.get(s.provider)
yield s.id, provider
end
2015-08-04 12:36:10 +03:00
def set_run_list node_name
s = get_server_by_key(node_name, parser.instance_key)
2015-08-14 13:28:03 +03:00
Devops::Db.connector.check_project_auth s.project, s.deploy_env, parser.current_user
2015-08-04 12:36:10 +03:00
Devops::Db.connector.set_server_run_list(s.id, parser.run_list)
end
2015-07-27 15:40:10 +03:00
def get_server_by_key id, key
2015-05-29 16:57:31 +03:00
mongo = Devops::Db.connector
key == "instance" ? mongo.server_by_instance_id(id) : mongo.server_by_chef_node_name(id)
2014-12-22 14:22:04 +03:00
end
2015-08-14 13:28:03 +03:00
def check_chef_node_name name, provider, knife
Devops::Db.connector.server_by_chef_node_name(name)
raise InvalidRecord.new("Server with name '#{name}' already exist")
2014-12-22 14:22:04 +03:00
rescue RecordNotFound => e
# server not found - OK
s = provider.servers.detect {|s| s["name"] == name}
2015-08-14 13:28:03 +03:00
raise InvalidRecord.new("#{provider.name} node with name '#{name}' already exist") unless s.nil?
s = knife.chef_node_list.detect {|n| n == name}
raise InvalidRecord.new("Chef node with name '#{name}' already exist") unless s.nil?
s = knife.chef_client_list.detect {|c| c == name}
raise InvalidRecord.new("Chef client with name '#{name}' already exist") unless s.nil?
2014-12-22 14:22:04 +03:00
end
2015-09-01 16:54:21 +03:00
private
2014-12-22 14:22:04 +03:00
2015-09-01 16:54:21 +03:00
def check_if_server_attrs_are_valid(body, user)
key_name = body["key"]
Devops::Db.connector.key(key_name) unless key_name.nil?
2014-12-22 14:22:04 +03:00
2015-09-01 16:54:21 +03:00
project = Devops::Db.connector.check_project_auth(body["project"], body["deploy_env"], user)
env = project.deploy_env(body["deploy_env"])
2014-12-22 14:22:04 +03:00
2015-09-01 16:54:21 +03:00
provider = env.provider_instance
server_name = body["name"]
check_chef_node_name(server_name, provider, KnifeFactory.instance) unless server_name.nil?
groups = body["groups"]
unless groups.nil?
buf = groups - provider.groups.keys
halt_response("Invalid security groups '#{buf.join("', '")}' for provider '#{provider.name}'") if buf.empty?
2014-12-22 14:22:04 +03:00
end
end
2015-11-09 18:57:22 +03:00
def set_last_operation_type_and_save(server, operation_type)
server.set_last_operation(operation_type)
Devops::Db.connector.server_update(server)
end
2015-09-01 16:54:21 +03:00
end
2014-12-22 14:22:04 +03:00
end
end
end