collins-cli 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
-