onering-agent 0.4.3
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 +15 -0
- data/bin/onering +68 -0
- data/lib/etc/facter.list +19 -0
- data/lib/onering.rb +32 -0
- data/lib/onering/api.rb +322 -0
- data/lib/onering/cli.rb +92 -0
- data/lib/onering/cli/assets.rb +138 -0
- data/lib/onering/cli/automation.rb +62 -0
- data/lib/onering/cli/call.rb +53 -0
- data/lib/onering/cli/devices.rb +98 -0
- data/lib/onering/cli/fact.rb +22 -0
- data/lib/onering/cli/reporter.rb +121 -0
- data/lib/onering/config.rb +62 -0
- data/lib/onering/logger.rb +141 -0
- data/lib/onering/plugins/assets.rb +54 -0
- data/lib/onering/plugins/authentication.rb +35 -0
- data/lib/onering/plugins/automation.rb +70 -0
- data/lib/onering/plugins/reporter.rb +360 -0
- data/lib/onering/util.rb +150 -0
- data/lib/onering/version.rb +8 -0
- metadata +188 -0
data/lib/onering/cli.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
module Onering
|
2
|
+
module CLI
|
3
|
+
require 'yaml'
|
4
|
+
require 'multi_json'
|
5
|
+
|
6
|
+
@_args = {}
|
7
|
+
|
8
|
+
class Plugin
|
9
|
+
def self.default_format(output_value=nil, args=nil)
|
10
|
+
if output_value.is_a?(Hash) or
|
11
|
+
(output_value.is_a?(Array) and output_value.compact.first.is_a?(Hash))
|
12
|
+
then
|
13
|
+
return 'yaml'
|
14
|
+
end
|
15
|
+
|
16
|
+
return nil
|
17
|
+
|
18
|
+
rescue Exception
|
19
|
+
return nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.inherited(subsclass)
|
23
|
+
@_subclasses ||= []
|
24
|
+
@_subclasses << subsclass unless @_subclasses.include?(subsclass)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.registered_plugins()
|
28
|
+
@_subclasses || []
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.connect(cliargs)
|
33
|
+
@_args = cliargs
|
34
|
+
|
35
|
+
return Onering::API.new({
|
36
|
+
'autoconnect' => cliargs[:autoconnect],
|
37
|
+
'config' => {
|
38
|
+
'url' => cliargs[:url],
|
39
|
+
'path' => cliargs[:path],
|
40
|
+
'source' => cliargs[:source],
|
41
|
+
'nosslverify' => cliargs[:nosslverify],
|
42
|
+
'params' => Hash[(cliargs[:param] || []).collect{|i| i.split('=',2) }],
|
43
|
+
'authentication' => {
|
44
|
+
'type' => (cliargs[:apikey_given] ? :token : nil),
|
45
|
+
'keyfile' => (cliargs[:apikey] || cliargs[:sslkey])
|
46
|
+
}.compact
|
47
|
+
}.compact
|
48
|
+
}.compact)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.output(data, format)
|
52
|
+
return nil if @_args[:quiet]
|
53
|
+
return nil if data.nil?
|
54
|
+
|
55
|
+
Onering::Logger.debug("Outputting data as #{format}:", "Onering::CLI")
|
56
|
+
|
57
|
+
case format
|
58
|
+
when 'text', 'txt'
|
59
|
+
if data.is_a?(Hash)
|
60
|
+
data.coalesce.each do |k,v|
|
61
|
+
puts k.to_s+': '+v.to_s
|
62
|
+
end
|
63
|
+
|
64
|
+
elsif data.is_a?(Array) and data.first.is_a?(Array)
|
65
|
+
puts data.collect{|i| i.map(&:to_s).join(@_args.get(:separator, "\t")) }.sort.join("\n")
|
66
|
+
|
67
|
+
else
|
68
|
+
[*data].each do |d|
|
69
|
+
if d.is_a?(Hash)
|
70
|
+
d.coalesce.each do |k,v|
|
71
|
+
puts k.to_s+': '+v.to_s
|
72
|
+
end
|
73
|
+
else
|
74
|
+
puts d unless d.nil? or d.to_s.empty?
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
when 'json'
|
80
|
+
puts MultiJson.dump(data, :pretty => true)
|
81
|
+
|
82
|
+
when 'yaml'
|
83
|
+
puts YAML.dump(data)
|
84
|
+
|
85
|
+
else
|
86
|
+
Onering::Logger.error("Unknown output format #{format.inspect}", "Onering::CLI")
|
87
|
+
end
|
88
|
+
|
89
|
+
return nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module Onering
|
2
|
+
module CLI
|
3
|
+
class Assets < Plugin
|
4
|
+
def self.configure(global={})
|
5
|
+
@api = Onering::CLI.connect(global).assets
|
6
|
+
|
7
|
+
@opts = ::Trollop::options do
|
8
|
+
banner <<-EOS
|
9
|
+
Search for, manipulate, and list values from one or more Onering assets.
|
10
|
+
|
11
|
+
Usage:
|
12
|
+
onering [global] assets [options] [subcommands]
|
13
|
+
|
14
|
+
Subcommands:
|
15
|
+
find <urlquery>
|
16
|
+
get <property> [property2 ..]
|
17
|
+
list <property> [property2 ..]
|
18
|
+
save
|
19
|
+
set <property> <value>
|
20
|
+
tag <tag1>[ tag2 .. tagN]
|
21
|
+
untag <tag1>[ tag2 .. tagN]
|
22
|
+
|
23
|
+
Options:
|
24
|
+
EOS
|
25
|
+
|
26
|
+
opt :query, "The Onering urlquery to filter devices by", :short => '-f', :type => :string
|
27
|
+
opt :id, "The node ID of the device to operate on", :short => '-i', :type => :string
|
28
|
+
|
29
|
+
# subcommands
|
30
|
+
stop_on %w{show get set list find save}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.run(args)
|
35
|
+
sc = args.shift
|
36
|
+
|
37
|
+
case (sc.downcase.to_sym rescue nil)
|
38
|
+
# -----------------------------------------------------------------------------
|
39
|
+
when :show
|
40
|
+
return @api.assets.show(args[0])
|
41
|
+
|
42
|
+
# -----------------------------------------------------------------------------
|
43
|
+
when :get
|
44
|
+
Onering::Logger.fatal!("Expected 1 parameter, got #{args.length}", "Onering::CLI::Assets") unless args.length == 1
|
45
|
+
|
46
|
+
if @opts[:query_given]
|
47
|
+
# doing this until a bulk field query endpoint is built
|
48
|
+
return @api.list('id', {
|
49
|
+
:filter => @opts[:query]
|
50
|
+
}).collect{|i| @api.get_field(i, args[0])}
|
51
|
+
|
52
|
+
elsif @opts[:id_given]
|
53
|
+
return @api.get_field(@opts[:id], args[0])
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
# -----------------------------------------------------------------------------
|
58
|
+
when :set
|
59
|
+
Onering::Logger.fatal!("Expected 2 parameters, got #{args.length}", "Onering::CLI::Assets") unless args.length == 2
|
60
|
+
|
61
|
+
if @opts[:query]
|
62
|
+
# doing this until a bulk field set endpoint is built
|
63
|
+
return @api.list('id', {
|
64
|
+
:filter => @opts[:query]
|
65
|
+
}).collect{|i| @api.set_field(i, args[0])}
|
66
|
+
|
67
|
+
elsif @opts[:id]
|
68
|
+
return @api.set_field(@opts[:id], args[0], args[1])
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
# -----------------------------------------------------------------------------
|
73
|
+
when :list
|
74
|
+
Onering::Logger.fatal!("Expected 1 parameter, got #{args.length}", "Onering::CLI::Assets") unless args.length >= 1
|
75
|
+
return @api.list(args, {
|
76
|
+
:filter => @opts[:query]
|
77
|
+
}.compact)
|
78
|
+
|
79
|
+
# -----------------------------------------------------------------------------
|
80
|
+
when :find
|
81
|
+
Onering::Logger.fatal!("Expected 1 parameter, got #{args.length}", "Onering::CLI::Assets") unless args.length == 1
|
82
|
+
return @api.find(args[0])
|
83
|
+
|
84
|
+
# -----------------------------------------------------------------------------
|
85
|
+
when :save
|
86
|
+
rv = @api.save(args[0] || @opts[:id]) do
|
87
|
+
# read from pipe
|
88
|
+
if not STDIN.tty?
|
89
|
+
STDIN.read()
|
90
|
+
|
91
|
+
# read from specified file
|
92
|
+
elsif (File.readable?(args[1]) rescue false)
|
93
|
+
File.read(args[1])
|
94
|
+
|
95
|
+
else
|
96
|
+
Onering::Logger.fatal!("Cannot save data, no input data specified", "Onering::CLI::Assets")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
rv.parsed_response
|
101
|
+
|
102
|
+
# -----------------------------------------------------------------------------
|
103
|
+
when :tag
|
104
|
+
Onering::Logger.fatal!("Expected 1 parameters, got #{args.length}", "Onering::CLI::Assets") unless args.length > 0
|
105
|
+
|
106
|
+
if @opts[:query]
|
107
|
+
# doing this until a bulk field set endpoint is built
|
108
|
+
@api.list('id', {
|
109
|
+
:filter => @opts[:query]
|
110
|
+
}).collect{|i| @api.get("devices/#{i}/tag/#{args.join('/')}") }
|
111
|
+
|
112
|
+
elsif @opts[:id]
|
113
|
+
@api.get("devices/#{@opts[:id]}/tag/#{args.join('/')}")
|
114
|
+
end
|
115
|
+
|
116
|
+
return nil
|
117
|
+
|
118
|
+
when :untag
|
119
|
+
Onering::Logger.fatal!("Expected 1 parameters, got #{args.length}", "Onering::CLI::Assets") unless args.length > 0
|
120
|
+
|
121
|
+
if @opts[:query]
|
122
|
+
# doing this until a bulk field set endpoint is built
|
123
|
+
@api.list('id', {
|
124
|
+
:filter => @opts[:query]
|
125
|
+
}).collect{|i| @api.get("devices/#{i}/untag/#{args.join('/')}") }
|
126
|
+
|
127
|
+
elsif @opts[:id]
|
128
|
+
@api.get("devices/#{@opts[:id]}/untag/#{args.join('/')}")
|
129
|
+
end
|
130
|
+
|
131
|
+
return nil
|
132
|
+
else
|
133
|
+
Onering::Logger.fatal!("Unknown subcommand #{sc.inspect}", "Onering::CLI::Assets")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Onering
|
2
|
+
module CLI
|
3
|
+
class Automation < Plugin
|
4
|
+
def self.configure(global={})
|
5
|
+
@requests = Onering::CLI.connect(global).automation_requests
|
6
|
+
@jobs = Onering::CLI.connect(global).automation_jobs
|
7
|
+
@tasks = Onering::CLI.connect(global).automation_tasks
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.run(args)
|
11
|
+
sc = args.shift # subcommand
|
12
|
+
ssc = args.shift # sub-subcommand
|
13
|
+
|
14
|
+
case (sc.downcase.to_sym rescue nil)
|
15
|
+
# -----------------------------------------------------------------------------
|
16
|
+
when :requests
|
17
|
+
@opts = ::Trollop::options do
|
18
|
+
banner <<-EOS
|
19
|
+
Options:
|
20
|
+
EOS
|
21
|
+
stop_on %w{show status requeue flush purge}
|
22
|
+
end
|
23
|
+
|
24
|
+
case (ssc.downcase.to_sym rescue nil)
|
25
|
+
when :show
|
26
|
+
return @requests.show(args[0])
|
27
|
+
|
28
|
+
when :requeue
|
29
|
+
return @requests.requeue_all_failed() if args[0].nil?
|
30
|
+
return @requests.requeue(args[0])
|
31
|
+
|
32
|
+
when :status
|
33
|
+
fields = (args.empty? ? ["status"] : args)
|
34
|
+
rv = {}
|
35
|
+
out = @requests.summary(fields)
|
36
|
+
|
37
|
+
_rejigger_hash = Proc.new do |h|
|
38
|
+
[*h].collect{|i|
|
39
|
+
[i['id'], (i['children'].nil? ? i['count'] : Hash[_rejigger_hash.call(i['children'])])]
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
return Hash[_rejigger_hash.call(out)]
|
44
|
+
|
45
|
+
when :flush
|
46
|
+
return @requests.flush_queue()
|
47
|
+
|
48
|
+
when :purge
|
49
|
+
return @requests.purge()
|
50
|
+
end
|
51
|
+
|
52
|
+
# -----------------------------------------------------------------------------
|
53
|
+
when :jobs
|
54
|
+
|
55
|
+
|
56
|
+
# -----------------------------------------------------------------------------
|
57
|
+
when :tasks
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Onering
|
2
|
+
module CLI
|
3
|
+
class Call < Plugin
|
4
|
+
def self.configure(global={})
|
5
|
+
@api = Onering::CLI.connect(global)
|
6
|
+
|
7
|
+
@opts = ::Trollop::options do
|
8
|
+
banner <<-EOS
|
9
|
+
Call an arbitrary Onering API endpoint and return the output
|
10
|
+
|
11
|
+
Usage:
|
12
|
+
onering call [options] [endpoint]
|
13
|
+
|
14
|
+
Examples:
|
15
|
+
# Returns the API status page at path /api/
|
16
|
+
$ onering call /
|
17
|
+
|
18
|
+
# Returns details about the authenticated user
|
19
|
+
$ onering call users/current
|
20
|
+
|
21
|
+
# Delete the device called '0bf29c'
|
22
|
+
$ onering call devices/0bf29c -m delete
|
23
|
+
|
24
|
+
Options:
|
25
|
+
EOS
|
26
|
+
opt :method, "The HTTP method to use when performing the request", :default => 'get', :short => "-m", :type => :string
|
27
|
+
opt :query, "A query string attribute to add to the request in the form of NAME=VALUE", :short => '-a', :type => :string, :multi => true
|
28
|
+
opt :header, "A 'Name: Value' header to add to the request", :short => '-H', :type => :string, :multi => true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.run(args)
|
33
|
+
data = STDIN.read() unless STDIN.tty?
|
34
|
+
|
35
|
+
headers = {
|
36
|
+
'Content-Type' => 'application/json'
|
37
|
+
}.merge(Hash[@opts[:header].collect{|i|
|
38
|
+
i.split(/[\:=]\s*/,2)
|
39
|
+
}])
|
40
|
+
|
41
|
+
rv = @api.request(@opts[:method], args.first, {
|
42
|
+
:body => data,
|
43
|
+
:headers => headers,
|
44
|
+
:query => Hash[@opts[:query].collect{|i|
|
45
|
+
i.split('=',2)
|
46
|
+
}]
|
47
|
+
})
|
48
|
+
|
49
|
+
return (rv.parsed_response rescue rv.response.body)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Onering
|
2
|
+
module CLI
|
3
|
+
class Devices < Plugin
|
4
|
+
def self.configure(global={})
|
5
|
+
@api = Onering::CLI.connect(global).assets
|
6
|
+
|
7
|
+
@opts = ::Trollop::options do
|
8
|
+
banner <<-EOS
|
9
|
+
[DEPRECATED in 0.1.3] Use the 'assets' plugin from now on.
|
10
|
+
|
11
|
+
Usage:
|
12
|
+
onering [global] report [options]
|
13
|
+
|
14
|
+
Options:
|
15
|
+
EOS
|
16
|
+
|
17
|
+
opt :query, "The Onering urlquery to filter devices by", :short => '-f', :type => :string
|
18
|
+
opt :id, "The node ID of the device to operate on", :short => '-i', :type => :string
|
19
|
+
|
20
|
+
# subcommands
|
21
|
+
stop_on %w{show get set list find save}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.run(args)
|
26
|
+
sc = args.shift
|
27
|
+
|
28
|
+
case (sc.downcase.to_sym rescue nil)
|
29
|
+
# -----------------------------------------------------------------------------
|
30
|
+
when :show
|
31
|
+
return @api.devices.show(args[0])
|
32
|
+
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
when :get
|
35
|
+
Onering::Logger.fatal!("Expected 1 parameter, got #{args.length}", "Onering::CLI::Devices") unless args.length == 1
|
36
|
+
|
37
|
+
if @opts[:query_given]
|
38
|
+
# doing this until a bulk field query endpoint is built
|
39
|
+
return @api.list('id', {
|
40
|
+
:filter => @opts[:query]
|
41
|
+
}).collect{|i| @api.get_field(i, args[0])}
|
42
|
+
|
43
|
+
elsif @opts[:id_given]
|
44
|
+
return @api.get_field(@opts[:id], args[0])
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
# -----------------------------------------------------------------------------
|
49
|
+
when :set
|
50
|
+
Onering::Logger.fatal!("Expected 2 parameters, got #{args.length}", "Onering::CLI::Devices") unless args.length == 2
|
51
|
+
|
52
|
+
if @opts[:query]
|
53
|
+
# doing this until a bulk field set endpoint is built
|
54
|
+
return @api.list('id', {
|
55
|
+
:filter => @opts[:query]
|
56
|
+
}).collect{|i| @api.set_field(i, args[0])}
|
57
|
+
|
58
|
+
elsif @opts[:id]
|
59
|
+
return @api.set_field(@opts[:id], args[0], args[1])
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# -----------------------------------------------------------------------------
|
64
|
+
when :list
|
65
|
+
Onering::Logger.fatal!("Expected 1 parameter, got #{args.length}", "Onering::CLI::Devices") unless args.length >= 1
|
66
|
+
return @api.list(args[0], {
|
67
|
+
:filter => [@opts[:query], args[1]].compact.join('/')
|
68
|
+
}.compact)
|
69
|
+
|
70
|
+
# -----------------------------------------------------------------------------
|
71
|
+
when :find
|
72
|
+
Onering::Logger.fatal!("Expected 1 parameter, got #{args.length}", "Onering::CLI::Devices") unless args.length == 1
|
73
|
+
return @api.find(args[0])
|
74
|
+
|
75
|
+
# -----------------------------------------------------------------------------
|
76
|
+
when :save
|
77
|
+
rv = @api.save(args[0] || @opts[:id]) do
|
78
|
+
# read from pipe
|
79
|
+
if not STDIN.tty?
|
80
|
+
STDIN.read()
|
81
|
+
|
82
|
+
# read from specified file
|
83
|
+
elsif (File.readable?(args[1]) rescue false)
|
84
|
+
File.read(args[1])
|
85
|
+
|
86
|
+
else
|
87
|
+
Onering::Logger.fatal!("Cannot save data, no input data specified", "Onering::CLI::Devices")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
rv.parsed_response
|
92
|
+
else
|
93
|
+
Onering::Logger.fatal!("Unknown subcommand #{sc.inspect}", "Onering::CLI::Devices")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|