maws 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/maws +10 -0
- data/lib/maws/chunk_source.rb +41 -0
- data/lib/maws/command.rb +62 -0
- data/lib/maws/command_loader.rb +28 -0
- data/lib/maws/command_options_parser.rb +37 -0
- data/lib/maws/commands/configure.rb +287 -0
- data/lib/maws/commands/console.rb +38 -0
- data/lib/maws/commands/create.rb +25 -0
- data/lib/maws/commands/describe.rb +15 -0
- data/lib/maws/commands/destroy.rb +11 -0
- data/lib/maws/commands/elb-add.rb +17 -0
- data/lib/maws/commands/elb-describe.rb +23 -0
- data/lib/maws/commands/elb-disable-zones.rb +17 -0
- data/lib/maws/commands/elb-enable-zones.rb +18 -0
- data/lib/maws/commands/elb-remove.rb +16 -0
- data/lib/maws/commands/set-prefix.rb +24 -0
- data/lib/maws/commands/set-security-groups.rb +442 -0
- data/lib/maws/commands/start.rb +11 -0
- data/lib/maws/commands/status.rb +25 -0
- data/lib/maws/commands/stop.rb +11 -0
- data/lib/maws/commands/teardown.rb +11 -0
- data/lib/maws/commands/volumes-cleanup.rb +22 -0
- data/lib/maws/commands/volumes-status.rb +43 -0
- data/lib/maws/commands/wait.rb +61 -0
- data/lib/maws/connection.rb +121 -0
- data/lib/maws/core_ext/object.rb +5 -0
- data/lib/maws/description/ebs.rb +40 -0
- data/lib/maws/description/ec2.rb +72 -0
- data/lib/maws/description/elb.rb +52 -0
- data/lib/maws/description/rds.rb +47 -0
- data/lib/maws/description.rb +78 -0
- data/lib/maws/instance/ebs.rb +45 -0
- data/lib/maws/instance/ec2.rb +144 -0
- data/lib/maws/instance/elb.rb +92 -0
- data/lib/maws/instance/rds.rb +84 -0
- data/lib/maws/instance.rb +167 -0
- data/lib/maws/instance_collection.rb +98 -0
- data/lib/maws/instance_display.rb +84 -0
- data/lib/maws/instance_matcher.rb +27 -0
- data/lib/maws/loader.rb +173 -0
- data/lib/maws/logger.rb +66 -0
- data/lib/maws/mash.rb +9 -0
- data/lib/maws/maws.rb +102 -0
- data/lib/maws/profile_loader.rb +92 -0
- data/lib/maws/specification.rb +127 -0
- data/lib/maws/ssh.rb +7 -0
- data/lib/maws/trollop.rb +782 -0
- data/lib/maws/volumes_command.rb +29 -0
- data/lib/maws.rb +25 -0
- metadata +115 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'maws/instance'
|
2
|
+
|
3
|
+
# for RDS instances name == aws_id
|
4
|
+
class Instance::RDS < Instance
|
5
|
+
def create
|
6
|
+
return if alive?
|
7
|
+
|
8
|
+
if config(:replica)
|
9
|
+
# READ REPLICA
|
10
|
+
info "creating RDS Read Replica #{name}..."
|
11
|
+
source_role_name = config(:source_role, true)
|
12
|
+
|
13
|
+
source_instance = instances.with_role(source_role_name).first
|
14
|
+
|
15
|
+
if source_instance.nil?
|
16
|
+
error "...can't create read replica - the source role '#{source_role_name}' doesn't exist"
|
17
|
+
return
|
18
|
+
end
|
19
|
+
|
20
|
+
unless source_instance.valid_read_replica_source?
|
21
|
+
error "...can't create read replica - source rds #{source_instance.name} is not valid (#{source_instance.status})!"
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
result = connection.rds.create_db_instance_read_replica(name, source_instance.name,
|
26
|
+
:instance_class => config(:instance_class, true),
|
27
|
+
:availability_zone => region_physical_zone)
|
28
|
+
else
|
29
|
+
info "creating RDS #{name}..."
|
30
|
+
|
31
|
+
# MASTER DB
|
32
|
+
create_opts = {}
|
33
|
+
create_opts[:engine] = config(:engine)
|
34
|
+
create_opts[:engine_version] = config(:engine_version)
|
35
|
+
create_opts[:instance_class] = config(:instance_class)
|
36
|
+
create_opts[:auto_minor_version_upgrade] = config(:auto_minor_version_upgrade)
|
37
|
+
create_opts[:allocated_storage] = config(:allocated_storage)
|
38
|
+
create_opts[:db_name] = config(:db_name)
|
39
|
+
create_opts[:db_parameter_group] = config(:db_parameter_group)
|
40
|
+
create_opts[:db_security_groups] = security_groups
|
41
|
+
create_opts[:backup_retention_period] = config(:backup_retention_period)
|
42
|
+
create_opts[:preferred_backup_window] = config(:preferred_backup_window)
|
43
|
+
create_opts[:preferred_maintenance_window] = config(:preferred_maintenance_window)
|
44
|
+
|
45
|
+
if config(:scope).eql?("region")
|
46
|
+
create_opts[:multi_az] = true
|
47
|
+
else
|
48
|
+
create_opts[:availability_zone] = @command_options.availability_zone
|
49
|
+
end
|
50
|
+
|
51
|
+
master_username = config(:master_username, true)
|
52
|
+
master_password = config(:master_password, true)
|
53
|
+
|
54
|
+
result = connection.rds.create_db_instance(name, master_username, master_password, create_opts)
|
55
|
+
end
|
56
|
+
|
57
|
+
sync_from_description(result)
|
58
|
+
info "...done (RDS #{name} is being created)\n\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
def destroy
|
62
|
+
return unless alive?
|
63
|
+
stoppable_states = %w(available failed storage-full incompatible-parameters incompatible-restore)
|
64
|
+
unless stoppable_states.include? status
|
65
|
+
info "can't destroy RDS #{aws_id} while it is #{status}"
|
66
|
+
return
|
67
|
+
end
|
68
|
+
connection.rds.delete_db_instance(aws_id, :skip_final_snapshot => true)
|
69
|
+
info "destroying RDS #{aws_id}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def valid_read_replica_source?
|
73
|
+
alive? && !config(:replica)
|
74
|
+
end
|
75
|
+
|
76
|
+
def service
|
77
|
+
:rds
|
78
|
+
end
|
79
|
+
|
80
|
+
def display_fields
|
81
|
+
super + [:endpoint_address, :endpoint_port]
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'maws/mash'
|
2
|
+
require 'maws/instance_matcher'
|
3
|
+
require 'maws/instance_display'
|
4
|
+
|
5
|
+
|
6
|
+
class Instance
|
7
|
+
attr_accessor :name
|
8
|
+
attr_accessor :region, :zone, :role, :index, :groups, :prefix
|
9
|
+
attr_reader :description
|
10
|
+
|
11
|
+
NA_STATUS = 'n/a'
|
12
|
+
|
13
|
+
def self.create(maws, config, prefix, zone, role, index, options = {})
|
14
|
+
options = mash(options)
|
15
|
+
|
16
|
+
service = options.service || config.combined[role].service
|
17
|
+
region = options.region || config.region
|
18
|
+
name = options.name || name_for(config, prefix, zone, role, index)
|
19
|
+
|
20
|
+
klass = Instance.const_get("#{service.to_s.upcase}")
|
21
|
+
|
22
|
+
klass.new(maws, config, name, region, prefix, zone, role, index)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.name_for(config, prefix, zone, role, index)
|
26
|
+
add_prefix = prefix.empty? ? "" : prefix + "."
|
27
|
+
"#{add_prefix}#{config.profile.name}-#{role}-#{index}#{zone}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(maws, config, name, region, prefix, zone, role, index)
|
31
|
+
@maws = maws
|
32
|
+
@config = config
|
33
|
+
@name = name
|
34
|
+
@region = region
|
35
|
+
@zone = zone
|
36
|
+
@role = role
|
37
|
+
@index = index
|
38
|
+
|
39
|
+
@prefix = prefix
|
40
|
+
|
41
|
+
@description = mash
|
42
|
+
@groups = %w(all)
|
43
|
+
end
|
44
|
+
|
45
|
+
def connection
|
46
|
+
@maws.connection
|
47
|
+
end
|
48
|
+
|
49
|
+
def instances
|
50
|
+
@maws.instances
|
51
|
+
end
|
52
|
+
|
53
|
+
def description=(description)
|
54
|
+
# never nil
|
55
|
+
@description = description || mash
|
56
|
+
end
|
57
|
+
|
58
|
+
def logical_zone
|
59
|
+
@zone
|
60
|
+
end
|
61
|
+
|
62
|
+
def physical_zone
|
63
|
+
@zone || @description.physical_zone || @config.specified_zones.first
|
64
|
+
end
|
65
|
+
|
66
|
+
def aws_id
|
67
|
+
description.aws_id
|
68
|
+
end
|
69
|
+
|
70
|
+
def status
|
71
|
+
description.status || 'n/a'
|
72
|
+
end
|
73
|
+
|
74
|
+
def region_zone
|
75
|
+
region + zone
|
76
|
+
end
|
77
|
+
|
78
|
+
def region_physical_zone
|
79
|
+
region + physical_zone
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def terminated?
|
84
|
+
status == 'terminated'
|
85
|
+
end
|
86
|
+
|
87
|
+
def alive?
|
88
|
+
aws_id && !terminated?
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_s
|
92
|
+
"#{name} #{status} #{aws_id}"
|
93
|
+
end
|
94
|
+
|
95
|
+
def inspect
|
96
|
+
"<#{self.class} #{to_s}>"
|
97
|
+
end
|
98
|
+
|
99
|
+
def has_approximate_status?(approximate_status)
|
100
|
+
if approximate_status == "n/a" or approximate_status == "terminated"
|
101
|
+
!alive?
|
102
|
+
elsif approximate_status == "ssh"
|
103
|
+
self.respond_to?(:ssh_available?) ? self.ssh_available? : has_approximate_status?("available")
|
104
|
+
elsif approximate_status == "running" || approximate_status == "available"
|
105
|
+
status == "running" || status == "available"
|
106
|
+
else
|
107
|
+
approximate_status == status
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def method_missing(method_name, *args, &block)
|
112
|
+
config(method_name) ||
|
113
|
+
description[method_name] ||
|
114
|
+
@config.command_line[method_name]
|
115
|
+
end
|
116
|
+
|
117
|
+
def config(key, required=false)
|
118
|
+
if required && @config.combined[role][key].nil?
|
119
|
+
raise ArgumentError.new("Missing required config: #{key}")
|
120
|
+
end
|
121
|
+
|
122
|
+
@config.combined[role][key]
|
123
|
+
end
|
124
|
+
|
125
|
+
def security_groups
|
126
|
+
groups = config(:security_groups).to_a.dup
|
127
|
+
groups << "#{service}_default"
|
128
|
+
|
129
|
+
if @config.profile.security_rules and @config.profile.security_rules[role]
|
130
|
+
groups << "#{@profile.name}-#{role_name}"
|
131
|
+
end
|
132
|
+
|
133
|
+
groups
|
134
|
+
end
|
135
|
+
|
136
|
+
def service
|
137
|
+
raise ArgumentError, "No service for generic instance"
|
138
|
+
end
|
139
|
+
|
140
|
+
def display_fields
|
141
|
+
[:zone, :name, :status]
|
142
|
+
end
|
143
|
+
|
144
|
+
def display
|
145
|
+
InstanceDisplay.new(self, display_fields)
|
146
|
+
end
|
147
|
+
|
148
|
+
def matches?(filters={})
|
149
|
+
approximate_status = filters.delete(:approximate_status)
|
150
|
+
matched = InstanceMatcher.matches?(self, filters)
|
151
|
+
|
152
|
+
# approximate status is not a single state
|
153
|
+
# it might require an ssh connection
|
154
|
+
matched &&= has_approximate_status?(approximate_status) if approximate_status
|
155
|
+
matched
|
156
|
+
end
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
# load all instance files
|
163
|
+
Dir.glob(File.dirname(__FILE__) + '/instance/*.rb') {|file| require file}
|
164
|
+
|
165
|
+
|
166
|
+
|
167
|
+
|
@@ -0,0 +1,98 @@
|
|
1
|
+
class InstanceCollection
|
2
|
+
include Enumerable
|
3
|
+
|
4
|
+
attr_accessor :members
|
5
|
+
|
6
|
+
def initialize(members = [])
|
7
|
+
@members = members.sort_by {|m| [m.region, m.zone.to_s, m.role.to_s, m.index || 1]}
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(instance)
|
11
|
+
@members << instance
|
12
|
+
end
|
13
|
+
|
14
|
+
def each
|
15
|
+
@members.each {|m| yield m}
|
16
|
+
end
|
17
|
+
|
18
|
+
def empty?
|
19
|
+
@members.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
def first
|
23
|
+
@members.first
|
24
|
+
end
|
25
|
+
|
26
|
+
def *(x)
|
27
|
+
@members * x
|
28
|
+
end
|
29
|
+
|
30
|
+
def matching(filters = {})
|
31
|
+
InstanceCollection.new(self.find_all {|i| i.matches?(filters)})
|
32
|
+
end
|
33
|
+
|
34
|
+
def not_matching(filters)
|
35
|
+
InstanceCollection.new(self.find_all {|i| !i.matches?(filters)})
|
36
|
+
end
|
37
|
+
|
38
|
+
def services
|
39
|
+
self.map {|i| i.service}.uniq
|
40
|
+
end
|
41
|
+
|
42
|
+
def roles
|
43
|
+
map{|i| i.role}.uniq
|
44
|
+
end
|
45
|
+
|
46
|
+
def zones
|
47
|
+
map{|i| i.zone}.uniq
|
48
|
+
end
|
49
|
+
|
50
|
+
def roles_in_order_of(roles_list)
|
51
|
+
roles.sort_by {|r| roles_list.index(r)}
|
52
|
+
end
|
53
|
+
|
54
|
+
# scopes
|
55
|
+
def specified
|
56
|
+
self.matching(:groups => 'specified')
|
57
|
+
end
|
58
|
+
|
59
|
+
def not_specified
|
60
|
+
self.not_matching(:groups => 'specified')
|
61
|
+
end
|
62
|
+
|
63
|
+
def aws
|
64
|
+
self.matching(:groups => 'aws')
|
65
|
+
end
|
66
|
+
|
67
|
+
def alive
|
68
|
+
self.matching(:alive? => true)
|
69
|
+
end
|
70
|
+
|
71
|
+
def not_alive
|
72
|
+
self.matching(:alive? => false)
|
73
|
+
end
|
74
|
+
|
75
|
+
def with_service(service)
|
76
|
+
self.matching(:service => service.to_sym)
|
77
|
+
end
|
78
|
+
|
79
|
+
def with_role(role)
|
80
|
+
self.matching(:role => role)
|
81
|
+
end
|
82
|
+
|
83
|
+
def with_zone(zone)
|
84
|
+
self.matching(:zone => zone)
|
85
|
+
end
|
86
|
+
|
87
|
+
def without_role(role)
|
88
|
+
self.not_matching(:role => role)
|
89
|
+
end
|
90
|
+
|
91
|
+
def ebs
|
92
|
+
with_service(:ebs)
|
93
|
+
end
|
94
|
+
|
95
|
+
def with_approximate_status(status)
|
96
|
+
self.matching(:approximate_status => status)
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class InstanceDisplay
|
2
|
+
def self.display_collection_for_role(role, instances)
|
3
|
+
headers = instances.first.display.headers
|
4
|
+
service_title = instances.first.service.to_s.downcase
|
5
|
+
info "\n\n**** " + role.upcase + " * #{service_title} ****************"
|
6
|
+
|
7
|
+
# separate by zone
|
8
|
+
previous_zone = instances.zones.first
|
9
|
+
rows = []
|
10
|
+
instances.map {|instance|
|
11
|
+
if previous_zone == instance.zone
|
12
|
+
rows << instance.display.values
|
13
|
+
else
|
14
|
+
previous_zone = instance.zone
|
15
|
+
rows << instance.display.blank_values
|
16
|
+
rows << instance.display.values
|
17
|
+
end
|
18
|
+
}
|
19
|
+
|
20
|
+
info table(headers, *rows)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(instance, fields)
|
24
|
+
@instance = instance
|
25
|
+
@fields = fields
|
26
|
+
end
|
27
|
+
|
28
|
+
def headers
|
29
|
+
@fields.map {|f| f.to_s.upcase.gsub('_', ' ')}
|
30
|
+
end
|
31
|
+
|
32
|
+
def values
|
33
|
+
@fields.collect do |field|
|
34
|
+
value = value(field, @instance.send(field))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def blank_values
|
39
|
+
@fields.map { "" }
|
40
|
+
end
|
41
|
+
|
42
|
+
def value(field, value)
|
43
|
+
if field.to_sym == :status
|
44
|
+
status(value)
|
45
|
+
else
|
46
|
+
value.to_s
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def status(status)
|
51
|
+
case status
|
52
|
+
when 'unknown' : '?'
|
53
|
+
when 'non-existant' : 'n/a'
|
54
|
+
when 'terminated' : 'n/a (terminated)'
|
55
|
+
else status.to_s
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def pretty_details
|
60
|
+
title = @instance.name.to_s.upcase
|
61
|
+
data = @instance.description.description
|
62
|
+
|
63
|
+
InstanceDisplay.pretty_describe(title, data)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.pretty_describe(title, data)
|
67
|
+
pretty_describe_heading(title)
|
68
|
+
if data.is_a? String
|
69
|
+
info data
|
70
|
+
else
|
71
|
+
ap data
|
72
|
+
end
|
73
|
+
pretty_describe_footer
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.pretty_describe_heading(title)
|
77
|
+
title = title[0,62]
|
78
|
+
info "++++++++++ " + title + " " + ("+" * (75 - title.length))
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.pretty_describe_footer
|
82
|
+
info "+-------------------------------------------------------------------------------------+\n\n\n"
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class InstanceMatcher
|
2
|
+
def self.matches?(instance, filters)
|
3
|
+
filters.each {|filter, expected_value|
|
4
|
+
value = instance.send(filter)
|
5
|
+
if value.is_a? Array
|
6
|
+
return false if value.find_all {|v| value_matches?(v, expected_value)}.empty?
|
7
|
+
else
|
8
|
+
return false unless value_matches?(value, expected_value)
|
9
|
+
end
|
10
|
+
}
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def self.value_matches?(value, expected_value)
|
16
|
+
if expected_value.is_a? Array
|
17
|
+
return false unless expected_value.include?(value)
|
18
|
+
else
|
19
|
+
if !expected_value # treat false/nil as the same
|
20
|
+
return !value
|
21
|
+
else
|
22
|
+
return false if expected_value != value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
data/lib/maws/loader.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
require 'maws/maws'
|
4
|
+
|
5
|
+
require 'maws/profile_loader'
|
6
|
+
require 'maws/command_loader'
|
7
|
+
|
8
|
+
require 'maws/command_options_parser'
|
9
|
+
|
10
|
+
class Loader
|
11
|
+
|
12
|
+
def initialize(base_path, config_config_path)
|
13
|
+
@base_path = base_path
|
14
|
+
@cc_path = config_config_path
|
15
|
+
@commands_path = File.expand_path("commands/", File.dirname(__FILE__))
|
16
|
+
|
17
|
+
# stores all config
|
18
|
+
@config = mash
|
19
|
+
@command = nil
|
20
|
+
|
21
|
+
Loader.config_file_must_exist!('main', @cc_path)
|
22
|
+
|
23
|
+
@command_options_parser = CommandOptionsParser.new(@config)
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_and_run
|
27
|
+
load_config
|
28
|
+
load_command
|
29
|
+
initialize_command
|
30
|
+
|
31
|
+
parse_command_line_options
|
32
|
+
verify_command
|
33
|
+
|
34
|
+
@maws = Maws.new(@config, @command)
|
35
|
+
@command.maws = @maws
|
36
|
+
|
37
|
+
@maws.run!
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def load_config
|
43
|
+
@config.config = mash(YAML.load_file(@cc_path))
|
44
|
+
|
45
|
+
@config.config.paths.commands = @commands_path
|
46
|
+
@config.config.paths.base = @base_path
|
47
|
+
@config.config.paths.config = @cc_path
|
48
|
+
@config.config.paths.template_output = 'tmp/'
|
49
|
+
|
50
|
+
expand_config_paths
|
51
|
+
|
52
|
+
load_aws_key
|
53
|
+
glob_available_profiles_and_commands
|
54
|
+
read_core_command_line_options
|
55
|
+
exit_with_basic_help_usage if needs_basic_help_usage?
|
56
|
+
exit_on_missing_profile
|
57
|
+
exit_on_missing_command
|
58
|
+
|
59
|
+
ProfileLoader.new(@config).load
|
60
|
+
end
|
61
|
+
|
62
|
+
def load_command
|
63
|
+
CommandLoader.new(@config).load
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize_command
|
67
|
+
@command = @config.command_class.new(@config)
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_command_line_options
|
71
|
+
@command_options_parser.process_command_options(@command)
|
72
|
+
@command.process_options
|
73
|
+
end
|
74
|
+
|
75
|
+
def verify_command
|
76
|
+
@command.verify_options
|
77
|
+
@command.verify_configs
|
78
|
+
end
|
79
|
+
|
80
|
+
def load_aws_key
|
81
|
+
Loader.config_file_must_exist!('aws_key', @config.config.paths.aws_key)
|
82
|
+
|
83
|
+
@config.aws_key = mash
|
84
|
+
|
85
|
+
key_id, secret_key = *File.read(@config.config.paths.aws_key).lines.map {|l| l.chomp}
|
86
|
+
@config.aws_key.key_id = key_id
|
87
|
+
@config.aws_key.secret_key = secret_key
|
88
|
+
end
|
89
|
+
|
90
|
+
def glob_available_profiles_and_commands
|
91
|
+
available_profiles = mash
|
92
|
+
available_commands = mash
|
93
|
+
|
94
|
+
Dir.glob(@config.config.paths.profiles + '/*.yml').each {|path|
|
95
|
+
name = File.basename(path,'.yml')
|
96
|
+
available_profiles[name] = path
|
97
|
+
}
|
98
|
+
|
99
|
+
Dir.glob(@config.config.paths.commands + '/*.rb').each {|path|
|
100
|
+
name = File.basename(path,'.rb')
|
101
|
+
available_commands[name] = path
|
102
|
+
}
|
103
|
+
|
104
|
+
@config.config.available_profiles = available_profiles
|
105
|
+
@config.config.available_commands = available_commands
|
106
|
+
end
|
107
|
+
|
108
|
+
def read_core_command_line_options
|
109
|
+
@config.command_line = mash
|
110
|
+
@config.command_line.profile_name = ARGV.shift
|
111
|
+
@config.command_line.command_name = ARGV.shift
|
112
|
+
end
|
113
|
+
|
114
|
+
def needs_basic_help_usage?
|
115
|
+
profile_name = @config.command_line.profile_name
|
116
|
+
command_name = @config.command_line.command_name
|
117
|
+
|
118
|
+
profile_name.blank? ||
|
119
|
+
command_name.blank? ||
|
120
|
+
profile_name == '-h' ||
|
121
|
+
profile_name == '--help' ||
|
122
|
+
command_name == '-h' ||
|
123
|
+
command_name == '--help'
|
124
|
+
end
|
125
|
+
|
126
|
+
def exit_with_basic_help_usage
|
127
|
+
profile_name = @config.command_line.profile_name
|
128
|
+
command_name = @config.command_line.command_name
|
129
|
+
|
130
|
+
profile_name = nil if profile_name == '-h' || profile_name == '--help'
|
131
|
+
command_name = nil if command_name == '-h' || command_name == '--help'
|
132
|
+
|
133
|
+
exit_with_basic_usage(profile_name, command_name)
|
134
|
+
end
|
135
|
+
|
136
|
+
def exit_on_missing_profile
|
137
|
+
profile_name = @config.command_line.profile_name
|
138
|
+
|
139
|
+
if @config.config.available_profiles[profile_name].blank?
|
140
|
+
puts "ERROR: no such profile: #{profile_name}"
|
141
|
+
exit_with_basic_usage(profile_name, @config.command_line.command_name)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def exit_on_missing_command
|
146
|
+
command_name = @config.command_line.command_name
|
147
|
+
|
148
|
+
if @config.config.available_commands[command_name].blank?
|
149
|
+
puts "ERROR: no such command: #{command_name}"
|
150
|
+
exit_with_basic_usage(@config.command_line.profile_name, command_name)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def exit_with_basic_usage(profile_name, command_name)
|
155
|
+
puts @command_options_parser.usage(profile_name, command_name)
|
156
|
+
exit(1)
|
157
|
+
end
|
158
|
+
|
159
|
+
def expand_config_paths
|
160
|
+
base_path = @config.config.paths.base
|
161
|
+
@config.config.paths.each { |path_name, path_location|
|
162
|
+
@config.config.paths[path_name] = File.expand_path(path_location, base_path)
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.config_file_must_exist!(name, path)
|
167
|
+
unless File.exists? path
|
168
|
+
error "No #{name} config: #{path} found. Quiting!"
|
169
|
+
exit(1)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
data/lib/maws/logger.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
class NullLogger
|
2
|
+
def error str
|
3
|
+
end
|
4
|
+
|
5
|
+
def warn str
|
6
|
+
end
|
7
|
+
|
8
|
+
def info str
|
9
|
+
end
|
10
|
+
|
11
|
+
def debug str
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
class RightAWSLogger
|
17
|
+
def error str
|
18
|
+
$stderr.puts "[ERROR]: #{str}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def warn str
|
22
|
+
puts "[warning]: #{str}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def info str
|
26
|
+
puts "---- " + str.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def debug str
|
30
|
+
puts str
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class MawsLogger
|
35
|
+
def error str
|
36
|
+
$stderr.puts "[ERROR]: #{str}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def warn str
|
40
|
+
puts "[warning]: #{str}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def info str
|
44
|
+
puts str
|
45
|
+
end
|
46
|
+
|
47
|
+
def debug str
|
48
|
+
puts str
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
$logger ||= MawsLogger.new
|
53
|
+
$right_aws_logger ||= RightAWSLogger.new
|
54
|
+
|
55
|
+
|
56
|
+
def info str
|
57
|
+
$logger.info str
|
58
|
+
end
|
59
|
+
|
60
|
+
def error str
|
61
|
+
$logger.error str
|
62
|
+
end
|
63
|
+
|
64
|
+
def warn str
|
65
|
+
$logger.warn str
|
66
|
+
end
|