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.
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
-