collins-cli 0.1.1 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +95 -36
- data/bin/collins +34 -15
- data/lib/collins/cli/find.rb +161 -0
- data/lib/collins/cli/formatter.rb +74 -0
- data/lib/collins/cli/ipam.rb +99 -0
- data/lib/collins/cli/log.rb +173 -0
- data/lib/collins/cli/mixins.rb +73 -0
- data/lib/collins/cli/modify.rb +144 -0
- data/lib/collins/cli/power.rb +77 -0
- data/lib/collins/cli/provision.rb +80 -0
- data/lib/collins-cli.rb +13 -0
- data/spec/collins__cli__find_spec.rb +48 -0
- data/spec/collins__cli__log_spec.rb +4 -0
- data/spec/collins__cli__modify_spec.rb +4 -0
- data/spec/collins__cli__power_spec.rb +4 -0
- data/spec/collins__cli__provision_spec.rb +4 -0
- data/spec/spec_helper.rb +2 -0
- metadata +52 -11
- data/bin/collins-action +0 -130
- data/bin/collins-find +0 -225
- data/bin/collins-log +0 -143
- data/bin/collins-modify +0 -149
data/bin/collins-modify
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# stands for collins-modify
|
3
|
-
# perform actions on asset attribtues in collins easily
|
4
|
-
|
5
|
-
require 'collins_auth'
|
6
|
-
require 'yaml'
|
7
|
-
require 'optparse'
|
8
|
-
|
9
|
-
SUCCESS = "SUCCESS"
|
10
|
-
ERROR = "ERROR"
|
11
|
-
VALID_STATUSES = ["ALLOCATED","CANCELLED","DECOMMISSIONED","INCOMPLETE","MAINTENANCE","NEW","PROVISIONED","PROVISIONING","UNALLOCATED"]
|
12
|
-
#TODO: this shouldnt be hardcoded. we should pull this from the API instead?
|
13
|
-
# should elegantly support user-defined states without changing this script
|
14
|
-
VALID_STATES = {
|
15
|
-
"ALLOCATED" => ["CLAIMED","SPARE","RUNNING_UNMONITORED","UNMONITORED"],
|
16
|
-
"MAINTENANCE" => ["AWAITING_REVIEW","HARDWARE_PROBLEM","HW_TESTING","HARDWARE_UPGRADE","IPMI_PROBLEM","MAINT_NOOP","NETWORK_PROBLEM","RELOCATION",'PROVISIONING_PROBLEM'],
|
17
|
-
"ANY" => ["RUNNING","STARTING","STOPPING","TERMINATED"],
|
18
|
-
}
|
19
|
-
log_levels = Collins::Api::Logging::Severity.constants.map(&:to_s)
|
20
|
-
|
21
|
-
options = {
|
22
|
-
:query_size => 9999,
|
23
|
-
:attributes => {},
|
24
|
-
:delete_attributes => [],
|
25
|
-
:log_level => 'NOTE',
|
26
|
-
:timeout => 120,
|
27
|
-
:config => nil
|
28
|
-
}
|
29
|
-
basename = File.basename(File.realpath($0))
|
30
|
-
parser = OptionParser.new do |opts|
|
31
|
-
opts.banner = "Usage: #{basename} [options]"
|
32
|
-
opts.on('-a','--set-attribute attribute:value',String,"Set attribute=value. : between key and value. attribute will be uppercased.") do |x|
|
33
|
-
if not x.include? ':'
|
34
|
-
puts '--set-attribute requires attribute:value, missing :value'
|
35
|
-
puts opts.help
|
36
|
-
exit 1
|
37
|
-
end
|
38
|
-
a,v = x.split(':')
|
39
|
-
options[:attributes][a.upcase.to_sym] = v
|
40
|
-
end
|
41
|
-
opts.on('-d','--delete-attribute attribute',String,"Delete attribute.") {|v| options[:delete_attributes] << v.to_sym }
|
42
|
-
opts.on('-S','--set-status status[:state]',String,'Set status (and optionally state) to status:state. Requires --reason') do |v|
|
43
|
-
status,state = v.split(':')
|
44
|
-
options[:status] = status.upcase if not status.nil? and not status.empty?
|
45
|
-
options[:state] = state.upcase if not state.nil? and not state.empty?
|
46
|
-
end
|
47
|
-
opts.on('-r','--reason REASON',String,"Reason for changing status/state.") {|v| options[:reason] = v }
|
48
|
-
opts.on('-l','--log MESSAGE',String,"Create a log entry.") do |v|
|
49
|
-
options[:log_message] = v
|
50
|
-
end
|
51
|
-
opts.on('-L','--level LEVEL',String, log_levels + log_levels.map(&:downcase),"Set log level. Default level is #{options[:log_level]}.") do |v|
|
52
|
-
options[:log_level] = v.upcase
|
53
|
-
end
|
54
|
-
opts.on('-t','--tags TAGS',Array,"Tags to work on, comma separated") {|v| options[:tags] = v.map(&:to_sym)}
|
55
|
-
opts.on('-C','--config CONFIG',String,'Use specific Collins config yaml for Collins::Client') {|v| options[:config] = v}
|
56
|
-
opts.on('-h','--help',"Help") {puts opts ; exit 0}
|
57
|
-
opts.separator ""
|
58
|
-
opts.separator "Allowed values (uppercase or lowercase is accepted):"
|
59
|
-
opts.separator <<_EOF_
|
60
|
-
Status (-S,--set-status):
|
61
|
-
#{VALID_STATUSES.join(', ')}
|
62
|
-
States (-S,--set-status):
|
63
|
-
#{VALID_STATES.keys.map {|k| "#{k} ->\n #{VALID_STATES[k].join(', ')}"}.join "\n "}
|
64
|
-
Log levels (-L,--level):
|
65
|
-
#{log_levels.join(', ')}
|
66
|
-
_EOF_
|
67
|
-
opts.separator ""
|
68
|
-
opts.separator "Examples:"
|
69
|
-
opts.separator <<_EOF_
|
70
|
-
Set an attribute on some hosts:
|
71
|
-
#{basename} -t 001234,004567 -a my_attribute:true
|
72
|
-
Delete an attribute on some hosts:
|
73
|
-
#{basename} -t 001234,004567 -d my_attribute
|
74
|
-
Delete and add attribute at same time:
|
75
|
-
#{basename} -t 001234,004567 -a new_attr:test -d old_attr
|
76
|
-
Set machine into maintenace noop:
|
77
|
-
#{basename} -t 001234 -S maintenance:maint_noop -r "I do what I want"
|
78
|
-
Set machine back to allocated:
|
79
|
-
#{basename} -t 001234 -S allocated:running -r "Back to allocated"
|
80
|
-
Set machine back to new without setting state:
|
81
|
-
#{basename} -t 001234 -S new -r "Dunno why you would want this"
|
82
|
-
Create a log entry:
|
83
|
-
#{basename} -t 001234 -l'computers are broken and everything is horrible' -Lwarning
|
84
|
-
Read from stdin:
|
85
|
-
cf -n develnode | #{basename} -d my_attribute
|
86
|
-
cf -n develnode -S allocated | #{basename} -a collectd_version:5.2.1-52
|
87
|
-
echo -e "001234\\n001235\\n001236"| #{basename} -a test_attribute:'hello world'
|
88
|
-
_EOF_
|
89
|
-
end.parse!
|
90
|
-
|
91
|
-
if ARGV.size > 0
|
92
|
-
# anything else left in ARGV is garbage
|
93
|
-
puts "Not sure what I am supposed to do with these arguments: #{ARGV.join(' ')}"
|
94
|
-
puts parser
|
95
|
-
exit 1
|
96
|
-
end
|
97
|
-
|
98
|
-
abort "See --help for #{basename} usage" if options[:attributes].empty? and options[:delete_attributes].empty? and options[:status].nil? and options[:log_message].nil?
|
99
|
-
abort "You need to provide a --reason when changing asset states!" if not options[:status].nil? and options[:reason].nil?
|
100
|
-
#TODO this is never checked because we are making option parser vet our options for levels. Catch OptionParser::InvalidArgument?
|
101
|
-
abort "Log level #{options[:log_level]} is invalid! Use one of #{log_levels.join(', ')}" unless Collins::Api::Logging::Severity.valid?(options[:log_level])
|
102
|
-
|
103
|
-
# if any statuses or states, validate them against allowed values
|
104
|
-
unless options[:status].nil?
|
105
|
-
abort "Invalid status #{options[:status]} (Should be in #{VALID_STATUSES.join(', ')})" unless VALID_STATUSES.include? options[:status]
|
106
|
-
states_for_status = VALID_STATES["ANY"].concat((VALID_STATES[options[:status]].nil?) ? [] : VALID_STATES[options[:status]])
|
107
|
-
abort "State #{options[:state]} doesn't apply to status #{options[:status]} (Should be one of #{states_for_status.join(', ')})" unless options[:state].nil? or states_for_status.include?(options[:state])
|
108
|
-
end
|
109
|
-
|
110
|
-
if options[:tags].nil? or options[:tags].empty?
|
111
|
-
# read tags from stdin. first field on the line is the tag
|
112
|
-
input = ARGF.readlines
|
113
|
-
options[:tags] = input.map{|l| l.split(/\s+/)[0] rescue nil}.compact.uniq
|
114
|
-
end
|
115
|
-
|
116
|
-
begin
|
117
|
-
@collins = Collins::Authenticator.setup_client timeout: options[:timeout], config_file: options[:config], prompt: true
|
118
|
-
rescue => e
|
119
|
-
abort "Unable to set up Collins client! #{e.message}"
|
120
|
-
end
|
121
|
-
|
122
|
-
def api_call desc, method, *varargs
|
123
|
-
success,message = begin
|
124
|
-
[@collins.send(method,*varargs),nil]
|
125
|
-
rescue => e
|
126
|
-
[false,e.message]
|
127
|
-
end
|
128
|
-
puts "#{success ? SUCCESS : ERROR}: #{desc}#{message.nil? ? nil : " (%s)" % e.message}"
|
129
|
-
success
|
130
|
-
end
|
131
|
-
|
132
|
-
exit_clean = true
|
133
|
-
options[:tags].each do |t|
|
134
|
-
if options[:log_message]
|
135
|
-
exit_clean = api_call("#{t} create #{options[:log_level].downcase} log #{options[:log_message].inspect}", :log!, t, options[:log_message], options[:log_level]) && exit_clean
|
136
|
-
end
|
137
|
-
options[:attributes].each do |k,v|
|
138
|
-
exit_clean = api_call("#{t} set #{k}=#{v}", :set_attribute!, t, k, v) && exit_clean
|
139
|
-
end
|
140
|
-
options[:delete_attributes].each do |k|
|
141
|
-
exit_clean = api_call("#{t} delete #{k}", :delete_attribute!, t, k) && exit_clean
|
142
|
-
end
|
143
|
-
if options[:status]
|
144
|
-
exit_clean = api_call("#{t} set status to #{options[:status]}#{options[:state] ? ":#{options[:state]}" : ''}", :set_status!, t, :status => options[:status], :state => options[:state], :reason => options[:reason]) && exit_clean
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
exit exit_clean ? 0 : 1
|
149
|
-
|