fluke/devops-client/lib/devops-client/handler/project.rb

488 lines
15 KiB
Ruby

require "devops-client/handler/provider"
require "devops-client/handler/image"
require "devops-client/handler/flavor"
require "devops-client/handler/network"
require "devops-client/handler/group"
require "devops-client/handler/user"
require "devops-client/options/project_options"
require "json"
require "set"
require "devops-client/output/project"
require "devops-client/handler/deploy_envs/deploy_env_factory"
class Project < Handler
attr_accessor :def_options
output_with Output::Project
def initialize(host, def_options={})
self.host = host
self.def_options = self.options = def_options
@options_parser = ProjectOptions.new(ARGV, def_options)
end
def handle
case ARGV[1]
when "create"
self.options = @options_parser.create_options
create_handler @options_parser.args
when "delete"
self.options = @options_parser.delete_options
delete_handler @options_parser.args
when "deploy"
self.options = @options_parser.deploy_options
deploy_handler @options_parser.args
when "list"
self.options = @options_parser.list_options
list_handler
output
when "multi"
case ARGV[2]
when "create"
self.options = @options_parser.multi_create_options
multi_create_handler @options_parser.args
else
@options_parser.invalid_multi_command
abort(I18n.t("handler.project.invalid_subcommand", :cmd => ARGV[1], :scmd => ARGV[2]))
end
when "servers"
self.options = @options_parser.servers_options
servers_handler @options_parser.args
output(output_type: :servers)
when "stacks"
self.options = @options_parser.stacks_options
stacks_handler @options_parser.args
output(output_type: :stacks)
when "set"
case ARGV[2]
when "run_list"
self.options = @options_parser.set_run_list_options
set_run_list_handler @options_parser.args
else
@options_parser.invalid_set_command
abort(I18n.t("handler.project.invalid_subcommand", :cmd => ARGV[1], :scmd => ARGV[2]))
end
when "show"
self.options = @options_parser.show_options
show_handler @options_parser.args
output(output_type: :show)
when "update"
self.options = @options_parser.update_options
update_handler @options_parser.args
when "user"
case ARGV[2]
when "add"
self.options = @options_parser.user_add_options
user_add_handler @options_parser.args
when "delete"
self.options = @options_parser.user_delete_options
user_delete_handler @options_parser.args
else
@options_parser.invalid_user_command
abort(I18n.t("handler.project.invalid_subcommand", :cmd => ARGV[1], :scmd => ARGV[2]))
end
when "test"
self.options = @options_parser.test_options
test_handler @options_parser.args
when "delete_servers"
self.options = @options_parser.delete_servers_options
delete_servers_handler @options_parser.args
else
@options_parser.invalid_command
end
end
def list_handler
@list = get "/projects"
end
def delete_handler args
r = inspect_parameters @options_parser.delete_params, args[2], args[3]
unless r.nil?
@options_parser.invalid_delete_command
abort(r)
end
o = {}
o[:deploy_env] = args[3] unless args[3].nil?
message = args[2]
message += ".#{args[3]}" unless args[3].nil?
if question(I18n.t("handler.project.question.delete", :name => message))
delete "/project/#{args[2]}", o
end
end
def show_handler args
r = inspect_parameters @options_parser.show_params, args[2]
unless r.nil?
@options_parser.invalid_show_command
abort(r)
end
@show = get_project_info_obj(args[2])
end
def update_handler args
r = inspect_parameters @options_parser.update_params, args[2], args[3]
unless r.nil?
@options_parser.invalid_update_command
abort(r)
end
update_object_from_file "project", args[2], args[3]
end
def create_handler args
file = self.options[:file]
unless file.nil?
json = File.read(file)
begin
JSON.parse(json)
rescue JSON::ParserError => e
abort(I18n.t("handler.project.create.invalid_json", :file => file))
end
post_body("/project", json)
else
r = inspect_parameters @options_parser.create_params, args[2]
unless r.nil?
@options_parser.invalid_create_command
abort(r)
end
unless self.options[:username].nil? || self.options[:password].nil?
self.auth[:username] = self.options[:username]
self.auth[:password] = self.options[:password]
self.def_options[:username] = self.auth[:username]
end
create_project args, :create_project_deploy_env_cmd
end
end
def servers_handler args
r = inspect_parameters @options_parser.servers_params, args[2], args[3]
unless r.nil?
@options_parser.invalid_servers_command
abort(r)
end
o = {}
unless args[3].nil?
o[:deploy_env] = args[3]
end
@servers = get "/project/#{args[2]}/servers", o
end
def stacks_handler args
project, deploy_env = args[2], args[3]
r = inspect_parameters @options_parser.stacks_params, project, deploy_env
unless r.nil?
@options_parser.invalid_stacks_command
abort(r)
end
options = {}
unless deploy_env.nil?
options[:deploy_env] = deploy_env
end
@list = get "/project/#{args[2]}/stacks", options
end
def user_add_handler args
r = inspect_parameters @options_parser.user_add_params, args[3], args[4]
unless r.nil?
@options_parser.invalid_user_add_command
abort(r)
end
q = {:users => args[4..-1]}
q[:deploy_env] = options[:deploy_env] unless options[:deploy_env].nil?
put "/project/#{args[3]}/user", q
end
def user_delete_handler args
r = inspect_parameters @options_parser.user_delete_params, args[3], args[4]
unless r.nil?
@options_parser.invalid_user_delete_command
abort(r)
end
q = {:users => args[4..-1]}
q[:deploy_env] = options[:deploy_env] unless options[:deploy_env].nil?
delete_body "/project/#{args[3]}/user", q.to_json
end
def multi_create_handler args
r = inspect_parameters @options_parser.multi_create_params, args[3]
unless r.nil?
@options_parser.invalid_multi_create_command
abort(r)
end
create_project args, :create_project_multi_deploy_env_cmd, :multi
i = Image.new(@host, self.def_options)
images, ti = i.list_handler, i.table
f = Flavor.new(@host, self.def_options)
flavors, tf = f.list_handler, f.table
g = Group.new(@host, self.def_options)
groups, tg = g.list_handler, g.table
list = list_handler
info, multi = {}, {:type => "multi", :name => args[3], :deploy_envs => []}
begin # Add environment
nodes, projects, servers = [], [], {}
deploy_env = {:identifier => enter_parameter("Deploy environment identifier: ")}
begin # Add server
server_name = args[3] + "_" + enter_parameter("Server name: " + args[3] + "_")
s = servers[server_name] = {}
s[:groups] = choose_indexes_from_list("Security groups", list, tg, "default", list.index("default")).map{|i| list[i]}
s[:flavor] = choose_flavor_cmd(flavors, tf)["name"]
s[:image] = choose_image_cmd(images, ti)["id"]
subprojects = s[:subprojects] = []
begin # Add project
o = {}
o[:project_id] = project_id = choose_project(list, table)
info[project_id] = get_project_info_obj(project_id) unless info.has_key?(project_id)
envs = info[project_id]["deploy_envs"].map{|de| de["identifier"]}
o[:project_env] = ( envs.size > 1 ? choose_project_env(envs) : envs[0] )
subprojects.push o
end while question("Add project?")
end while question("Add server?")
deploy_env[:servers] = servers
multi[:deploy_envs].push deploy_env
end while question(I18n.t("handler.project.question.add_env"))
puts JSON.pretty_generate(multi)
post "/project", :json => multi.to_json if question(I18n.t("handler.project.question.create"))
end
def set_run_list_handler args
r = inspect_parameters @options_parser.set_run_list_params, args[3], args[4], args[5]
unless r.nil?
@options_parser.invalid_set_run_list_command
abort(r)
end
run_list = []
args[5..args.size].each do |e|
run_list += e.split(",")
end
if run_list.empty?
exit unless question(I18n.t("handler.project.run_list.empty"))
else
exit unless DeployEnv.validate_run_list(run_list)
end
put "/project/#{args[3]}/#{args[4]}/run_list", run_list
end
def deploy_handler args
r = inspect_parameters @options_parser.deploy_params, args[2], args[3]
unless r.nil?
@options_parser.invalid_deploy_command
abort(r)
end
q = {}
q[:servers] = options[:servers] unless options[:servers].nil?
q[:deploy_env] = args[3] unless args[3].nil?
job_ids = post "/project/#{args[2]}/deploy", q
reports_urls(job_ids)
end
def test_handler args
r = inspect_parameters @options_parser.test_params, args[2], args[3]
unless r.nil?
@options_parser.invalid_test_command
abort(r)
end
job_ids = post "/project/test/#{args[2]}/#{args[3]}"
reports_urls(job_ids)
end
protected
def get_project_info_obj project_id
get("/project/#{project_id}")
end
def create_project args, env_method_name, type=nil
project_name = args[2]
providers = {}
providers[:obj], providers[:table] = fetcher.fetch_with_table('provider')
begin
project = get_project_info_obj(project_name)
puts_warn I18n.t("handler.project.exist", :project => project_name)
names = project["deploy_envs"].map{|de| de["identifier"]}
new_envs = []
while question(I18n.t("handler.project.question.add_env"))
new_envs << method(env_method_name).call(project_name, providers, names)
break if self.options[:no_ask]
end
puts JSON.pretty_generate(new_envs)
if question(I18n.t("handler.project.question.update_with_new_envs"))
new_envs.each do |env|
post "/project/#{project_name}/deploy_env", env
end
end
rescue NotFound => e
project = create_project_cmd(project_name, providers, env_method_name)
project[:name] = args[2]
puts json = JSON.pretty_generate(project)
post_body("/project", json) if question(I18n.t("handler.project.question.create"))
end
end
def create_project_cmd project_name, providers, env_method
project = {:deploy_envs => []}
names = []
begin
d = method(env_method).call(project_name, providers, names)
project[:deploy_envs].push d
break if self.options[:no_ask]
end while question(I18n.t("handler.project.question.add_env"))
project
end
def create_project_deploy_env_cmd project, providers, names
d = {}
set_identifier(d, names)
set_provider(d, providers)
de = DeployEnvFactory.create(d[:provider], @host, self.options, self.auth)
de.fill d
=begin
unless d[:provider] == "static"
set_flavor(d, buf)
set_image(d, buf)
vpc_id = set_subnets(d, buf)
set_groups(d, buf, vpc_id)
end
set_users(d, buf)
unless self.options[:run_list].nil?
self.options[:run_list] = self.options[:run_list].split(",").map{|e| e.strip}
abort("Invalid run list: '#{self.options[:run_list].join(",")}'") unless Project.validate_run_list(self.options[:run_list])
end
set_parameter d, :run_list do
set_run_list_cmd project, d[:identifier]
end
unless self.options[:no_expires]
set_parameter d, :expires do
s = enter_parameter_or_empty(I18n.t("options.project.create.expires") + ": ").strip
s.empty? ? nil : s
end
end
=end
d
end
def create_project_multi_deploy_env_cmd project, providers, names
d = {}
set_identifier(d, names)
set_provider(d, providers)
buf = providers[d[:provider]]
set_flavor(d, buf)
set_image(d, buf)
vpc_id = set_subnets(d, buf)
set_groups(d, buf, vpc_id)
set_users(d, buf)
unless self.options[:run_list].nil?
self.options[:run_list] = self.options[:run_list].split(",").map{|e| e.strip}
abort("Invalid run list: '#{self.options[:run_list].join(",")}'") unless DeployEnv.validate_run_list(self.options[:run_list])
end
set_parameter d, :run_list do
set_run_list_cmd project, d[:identifier]
end
unless self.options[:no_expires]
set_parameter d, :expires do
s = enter_parameter_or_empty(I18n.t("options.project.create.expires") + ": ").strip
s.empty? ? nil : s
end
end
d
end
def set_identifier d, names
set_parameter d, :identifier do
begin
n = enter_parameter I18n.t("handler.project.create.env") + ": "
if names.include?(n)
puts I18n.t("handler.project.create.env_exist", :env => n)
raise ArgumentError
else
names.push n
n
end
rescue ArgumentError
retry
end
end
end
def set_provider d, providers
set_parameter d, :provider do
providers[:obj][ choose_number_from_list(I18n.t("headers.provider"), providers[:obj], providers[:table]) ]
end
end
def set_parameter obj, key
if self.options[key].nil?
obj[key] = yield
else
obj[key] = self.options[key]
end
end
# returns project id
def choose_project projects, table=nil
abort(I18n.t("handler.project.list.empty")) if projects.empty?
projects[ choose_number_from_list(I18n.t("headers.project"), projects, table) ]
end
# returns project env
def choose_project_env project_envs, table=nil
abort(I18n.t("handler.project.env.list.empty")) if project_envs.empty?
project_envs[ choose_number_from_list(I18n.t("headers.project_env"), project_envs, table) ]
end
def data_to_output
@list || @show || @servers || @test
end
def delete_servers_handler(args)
project, env = args[2], args[3]
if error = inspect_parameters(@options_parser.delete_servers_params, project, env)
@options_parser.invalid_delete_servers_command
abort(error)
end
ask_for_delete_servers(project, env)
body = {
deploy_env: env,
dry_run: false
}
response = delete("/project/#{project}/servers", body)
reports_urls(response['reports'])
end
private
def ask_for_delete_servers(project, env)
body = {
deploy_env: env,
dry_run: true
}
to_delete = delete("/project/#{project}/servers", body)['to_delete']
if to_delete.empty?
abort "There are no servers to delete."
else
puts "Servers to delete:\n----\n"
puts to_delete.join("\n")
puts '----'
end
if @options[:dry_run] || !question('Are you sure to delete them? ')
abort
end
end
end