2014-12-22 14:22:04 +03:00
|
|
|
require 'rufus-scheduler'
|
|
|
|
|
require "uri"
|
|
|
|
|
|
|
|
|
|
require "commands/status"
|
2015-08-12 11:37:17 +03:00
|
|
|
#require "commands/server"
|
2014-12-22 14:22:04 +03:00
|
|
|
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
|
2015-08-12 11:37:17 +03:00
|
|
|
# extend ServerCommands
|
2014-12-22 14:22:04 +03:00
|
|
|
extend BootstrapTemplatesCommands
|
|
|
|
|
|
|
|
|
|
scheduler = Rufus::Scheduler.new
|
|
|
|
|
|
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
|
|
|
|
|
::Provider::ProviderFactory.get(provider).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
|
|
|
|
|
delete_server(s, Devops::Db.connector, DevopsLogger.logger)
|
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
|
2015-07-27 15:40:10 +03:00
|
|
|
dir = DevopsConfig[:report_dir_v2]
|
2015-08-03 15:09:04 +03:00
|
|
|
uri = URI.parse(parser.request.url)
|
2015-08-05 14:05:14 +03:00
|
|
|
file = prepare_create_server do |project, env, user, body|
|
|
|
|
|
jid = CreateServerWorker.perform_async(dir, body, user, DevopsConfig.config)
|
2015-07-27 15:40:10 +03:00
|
|
|
Worker.set_status jid, Worker::STATUS::IN_QUEUE
|
2015-08-12 14:42:21 +03:00
|
|
|
DevopsLogger.logger.info "Job '#{jid}' has been queued"
|
2015-07-27 15:40:10 +03:00
|
|
|
uri.path = "#{DevopsConfig[:url_prefix]}/v2.0/report/" + jid
|
2015-08-05 14:05:14 +03:00
|
|
|
uri.to_s
|
2015-07-27 15:40:10 +03:00
|
|
|
end
|
|
|
|
|
sleep 1
|
2015-08-05 14:05:14 +03:00
|
|
|
[file]
|
2014-12-22 14:22:04 +03:00
|
|
|
end
|
|
|
|
|
|
2015-07-30 15:37:43 +03:00
|
|
|
def prepare_create_server
|
|
|
|
|
body = parser.create
|
|
|
|
|
user = parser.current_user
|
2015-07-27 15:40:10 +03:00
|
|
|
key_name = body["key"]
|
|
|
|
|
new_key = Devops::Db.connector.key(key_name) unless key_name.nil?
|
|
|
|
|
|
|
|
|
|
p = Devops::Db.connector.check_project_auth(body["project"], body["deploy_env"], user)
|
|
|
|
|
env = p.deploy_env(body["deploy_env"])
|
|
|
|
|
|
|
|
|
|
provider = ::Provider::ProviderFactory.get(env.provider)
|
|
|
|
|
server_name = body["name"]
|
|
|
|
|
check_chef_node_name(server_name, provider) 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?
|
|
|
|
|
end
|
|
|
|
|
|
2015-08-05 14:05:14 +03:00
|
|
|
yield p, env, user, body
|
|
|
|
|
|
|
|
|
|
#Server.extract_servers(provider, p, env, body, user)
|
2014-12-22 14:22:04 +03:00
|
|
|
end
|
|
|
|
|
|
2015-07-30 15:37:43 +03:00
|
|
|
def pause_server node_name
|
|
|
|
|
s = Server.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-07-27 15:40:10 +03:00
|
|
|
provider = ::Provider::ProviderFactory.get(s.provider)
|
|
|
|
|
r = provider.pause_server s
|
|
|
|
|
if r.nil?
|
|
|
|
|
"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
|
|
|
|
|
s = Server.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-07-27 15:40:10 +03:00
|
|
|
provider = ::Provider::ProviderFactory.get(s.provider)
|
|
|
|
|
r = provider.unpause_server s
|
|
|
|
|
if r.nil?
|
|
|
|
|
"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
|
|
|
|
|
Devops::Db.connector.server_update(s)
|
|
|
|
|
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
|
|
|
|
|
Devops::Db.connector.server_update(s)
|
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-08-10 13:17:04 +03:00
|
|
|
s, rl, bt = prepare_bootstrap_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-08-11 19:47:54 +03:00
|
|
|
options = {
|
|
|
|
|
:bootstrap_template => bt,
|
|
|
|
|
:cert_path => cert.path,
|
|
|
|
|
:run_list => rl
|
|
|
|
|
}
|
|
|
|
|
r = two_phase_bootstrap s, options, out
|
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-08-10 13:01:34 +03:00
|
|
|
s, rl, bt = prepare_bootstrap_server
|
2015-07-27 15:40:10 +03:00
|
|
|
dir = DevopsConfig[:report_dir_v2]
|
|
|
|
|
files = []
|
|
|
|
|
uri = URI.parse(@request.url)
|
|
|
|
|
h = s.to_hash
|
|
|
|
|
h["_id"] = s.id
|
2015-08-10 13:01:34 +03:00
|
|
|
jid = BootstrapWorker.perform_async(dir, s.provider, h, bt, parser.current_user, DevopsConfig.config)
|
2015-07-27 15:40:10 +03:00
|
|
|
Worker.set_status jid, Worker::STATUS::IN_QUEUE
|
2015-08-10 13:10:50 +03:00
|
|
|
DevopsLogger.logger.info "Job '#{jid}' has been started"
|
2015-07-27 15:40:10 +03:00
|
|
|
uri.path = "#{DevopsConfig[:url_prefix]}/v2.0/report/" + jid
|
|
|
|
|
uri.query = nil
|
|
|
|
|
uri.fragment = nil
|
|
|
|
|
files.push uri.to_s
|
|
|
|
|
sleep 1
|
|
|
|
|
files
|
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-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
|
|
|
|
|
|
|
|
provider = ::Provider::ProviderFactory.get(s.provider)
|
|
|
|
|
|
|
|
|
|
check_chef_node_name(name, provider) unless name.nil?
|
|
|
|
|
unless t.nil?
|
|
|
|
|
templates = get_templates
|
|
|
|
|
halt_response("Invalid bootstrap template '#{t}', available values: #{templates.join(", ")}", 400) unless templates.include?(t)
|
|
|
|
|
end
|
|
|
|
|
s.chef_node_name = name || provider.create_default_chef_node_name(s)
|
2015-08-10 13:01:34 +03:00
|
|
|
return s, rl || d.run_list, t
|
2015-07-27 15:40:10 +03:00
|
|
|
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
|
|
|
|
|
prepare_tags do |id, provider|
|
|
|
|
|
provider.set_tags id, parser.tags
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def unset_tags node_name
|
|
|
|
|
prepare_tags do |id, provider|
|
|
|
|
|
provider.unset_tags id, parser.tags
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def prepare_tags 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
|
|
|
|
|
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)
|
|
|
|
|
user = parser.current_user
|
|
|
|
|
Devops::Db.connector.check_project_auth s.project, s.deploy_env, user
|
|
|
|
|
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-07-27 15:40:10 +03:00
|
|
|
def check_chef_node_name name, provider
|
2015-05-29 16:57:31 +03:00
|
|
|
mongo = Devops::Db.connector
|
|
|
|
|
mongo.server_by_chef_node_name name
|
2014-12-22 14:22:04 +03:00
|
|
|
halt(400, "Server with name '#{name}' already exist")
|
|
|
|
|
rescue RecordNotFound => e
|
|
|
|
|
# server not found - OK
|
|
|
|
|
s = provider.servers.detect {|s| s["name"] == name}
|
|
|
|
|
halt(400, "#{provider.name} node with name '#{name}' already exist") unless s.nil?
|
2015-08-11 19:47:54 +03:00
|
|
|
s = KnifeFactory.instance.chef_node_list.detect {|n| n == name}
|
2014-12-22 14:22:04 +03:00
|
|
|
halt(400, "Chef node with name '#{name}' already exist") unless s.nil?
|
2015-08-11 19:47:54 +03:00
|
|
|
s = KnifeFactory.instance.chef_client_list.detect {|c| c == name}
|
2014-12-22 14:22:04 +03:00
|
|
|
halt(400, "Chef client with name '#{name}' already exist") unless s.nil?
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class ExpireHandler
|
|
|
|
|
include ServerCommands
|
|
|
|
|
|
|
|
|
|
def initialize server, logger
|
|
|
|
|
@server = server
|
|
|
|
|
@logger = logger
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def call(job)
|
|
|
|
|
@logger.info("Removing node '#{@server.chef_node_name}' form project '#{@server.project}' and env '#{@server.deploy_env}'")
|
|
|
|
|
begin
|
2015-05-29 16:57:31 +03:00
|
|
|
delete_server(@server, Devops::Db.connector, @logger)
|
2014-12-22 14:22:04 +03:00
|
|
|
rescue => e
|
|
|
|
|
logger.error "ExpiredHandler error: " + e.message
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|