This commit is contained in:
amartynov 2015-11-17 17:09:44 +03:00
commit 2611f5bb7c
12 changed files with 152 additions and 14 deletions

View File

@ -33,7 +33,7 @@ module DevopsClient
if config[:host].nil?
abort(I18n.t("config.invalid.host"), :file => @@config_file)
end
[:api, :username, :password].each do |key|
[:api, :username].each do |key|
if config[key].nil? or config[key].empty?
abort(I18n.t("config.invalid.empty", :file => @@config_file, :key => key))
end

View File

@ -5,8 +5,8 @@ module Outputtable
end
def outputter
raise 'You should use "output_with" method to define outputter' unless defined?(outputter_class)
@outputter ||= outputter_class.new(data_to_output, options.merge(current_command: current_command))
raise 'You should use "output_with" method to define outputter' unless self.class.outputter_class
@outputter ||= self.class.outputter_class.new(data_to_output, options.merge(current_command: current_command))
end
def output(options={})
@ -19,10 +19,9 @@ module Outputtable
end
module ClassMethods
attr_reader :outputter_class
def output_with(klass)
define_method :outputter_class do
klass
end
@outputter_class = klass
end
end

View File

@ -84,6 +84,10 @@ class Project < Handler
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
output(output_type: :delete_servers)
else
@options_parser.invalid_command
end
@ -440,4 +444,39 @@ protected
@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
}
@list = delete("/project/#{project}/servers", body)
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

View File

@ -3,7 +3,7 @@ require "set"
class ProjectOptions < CommonOptions
commands :create, :delete, :deploy, :list, {:multi => [:create]}, :servers, :stacks, {:set => [:run_list]}, :show, :test, :update, {:user => [:add, :delete]}
commands :create, :delete, :deploy, :list, {:multi => [:create]}, :servers, :stacks, {:set => [:run_list]}, :show, :test, :update, {:user => [:add, :delete]}, :delete_servers
def initialize args, def_options
super(args, def_options)
@ -23,6 +23,7 @@ class ProjectOptions < CommonOptions
self.user_add_params = [id, "USER_NAME", "[USER_NAME ...]"]
self.user_delete_params = [id, "USER_NAME", "[USER_NAME ...]"]
self.test_params = [id, env]
self.delete_servers_params = [id, "[#{env}]"]
end
def create_options
@ -65,7 +66,6 @@ class ProjectOptions < CommonOptions
# end
end
end
def user_add_options
@ -94,4 +94,10 @@ class ProjectOptions < CommonOptions
end
end
def delete_servers_options
self.options do |parser, options|
parser.recognize_option_value(:dry_run, 'project', type: :switch, default: false, switch_value: true, i18n_scope: 'delete_servers')
end
end
end

View File

@ -27,6 +27,8 @@ module Output
when :test
title = I18n.t("output.title.project.test", :project => ARGV[2], :env => ARGV[3])
create_test(@data)
when :delete_servers
return delete_servers_output
else
title = I18n.t("output.title.project.list")
create_list(@data)
@ -149,5 +151,22 @@ module Output
headers_and_rows(stacks, fields_to_output)
end
def delete_servers_output
output = ''
if @data['deleted'].empty?
output << 'There are no deleted servers.'
else
output << "Deleted servers:\n----\n"
output << @data['deleted'].join("\n")
end
if !@data['failed'].empty?
output << "\nThere were errors during deleting these servers:\n----\n"
output << @data['failed'].join("\n")
end
output
end
end
end

View File

@ -343,6 +343,8 @@ en:
deploy_env: "Delete user from deploy environment"
deploy:
servers: "Servers list (comma separated) for deploy"
delete_servers:
dry_run: "Only show servers to delete, no real deleting"
script:
params: Script arguments (comma separated list)
server:

View File

@ -3,6 +3,8 @@ require "db/mongo/models/project"
require "workers/project_test_worker"
require "app/api2/parsers/project"
require "lib/project/type/types_factory"
require "lib/executors/server_executor"
require_relative "../helpers/version_2.rb"
require_relative "request_handler"
@ -298,6 +300,32 @@ module Devops
return [jid]
end
def delete_project_servers(project_id)
env_id, dry_run = parser.delete_project_servers
Devops::Db.connector.project(project_id)
servers = Devops::Db.connector.servers(project_id, env_id)
info = {to_delete: servers.map(&:id)}
if !dry_run
info.merge!(delete_chosen_servers!(servers))
end
info
end
private
def delete_chosen_servers!(servers)
deleted, failed = [], []
servers.each do |server|
begin
Devops::Executor::ServerExecutor.new(server, '').delete_server
deleted << server.id
rescue
failed << server.id
end
end
{deleted: deleted, failed: failed}
end
end
end
end

View File

@ -28,6 +28,14 @@ module Devops
check_param val, String, msg, _nil, empty
end
def check_boolean val, msg
begin
check_param val, TrueClass, msg, false, true
rescue
check_param val, FalseClass, msg, false, true
end
end
def check_array val, msg, vals_type=String, _nil=false, empty=false
check_param val, Array, msg, _nil, empty
val.each {|v| raise Devops::ValidationError.new(msg) unless v.is_a?(vals_type)} unless val.nil?
@ -60,7 +68,7 @@ module Devops
end
end
if val.is_a?(type)
raise Devops::ValidationError.new(msg) if val.empty? and !empty
raise Devops::ValidationError.new(msg) if !empty && val.empty?
val
else
raise Devops::ValidationError.new(msg)

View File

@ -97,6 +97,13 @@ module Devops
servers = check_array(obj["servers"], "Parameter 'servers' should be a not empty array of strings", String, true)
return deploy_env, servers
end
def delete_project_servers
body = create_object_from_json_body
dry_run = check_boolean(body["dry_run"], "Parameter 'dry_run' must be a boolean")
deploy_env = check_string(body["deploy_env"], "Parameter 'deploy_env' must be a not empty string", true)
[deploy_env, dry_run]
end
end
end
end

View File

@ -166,10 +166,37 @@ module Devops
# "id": "nstance id"
# }
# ]
app.get_with_headers "/project/:project/servers", :headers => [:accept] do |project|
servers_routes_hash = {}
servers_routes_hash["GET"] = lambda { |project|
check_privileges("project", "r")
json Devops::API2_0::Handler::Project.new(request).project_servers(project).map(&:to_hash)
end
}
# Deletes project servers
#
# * *Request*
# - method : PATCH
# - headers :
# - Accept: application/json
# - Content-Type: application/json
# - body :
# {
# "dry_run": false # set to true if you'd like to just see list of servers to delete
# "deploy_env": null # set to env's identifier to delete that env's servers
# }
#
# * *Returns* :
# 200 -
# {
# "to_delete": ['server1', 'server2'],
# "deleted": ['server1'],
# "failed": ['server2']
# }
servers_routes_hash["DELETE"] = lambda { |project_id|
check_privileges("project", "w")
json Devops::API2_0::Handler::Project.new(request).delete_project_servers(project_id)
}
app.multi_routes "/project/:project/servers", {}, servers_routes_hash
# Get project stacks
#

View File

@ -116,7 +116,9 @@ module Devops
return 0
end
rescue => e
@out << e.message
@out.puts e.message
@out.puts e.backtrace.join("\n")
DevopsLogger.logger.error e.message
roll_back
mongo.server_delete @server.id
@ -360,7 +362,7 @@ module Devops
deploy_info.delete("use_json_file")
json = nil
dir = DevopsConfig.config[:project_info_dir]
file = deploy_info["json_file"] || "#{@server.project}_#{@server.deploy_env}_#{Time.new.to_i}"
file = deploy_info.delete("json_file") || "#{@server.project}_#{@server.deploy_env}_#{Time.new.to_i}"
path = File.join(dir, file)
if File.exists?(path)
json = File.read(path)

View File

@ -110,7 +110,8 @@ module Provider
vpcId = nil
unless subnets.empty?
options["SubnetId"] = subnets[0]
vpcId = self.networks.detect{|n| n["name"] == options["SubnetId"]}["vpcId"]
network = self.networks.detect{|n| n["name"] == options["SubnetId"]}
vpcId = network["vpcId"] if network
if vpcId.nil?
out << "Can not get 'vpcId' by subnet name '#{options["SubnetId"]}'\n"
return false