onering-client 0.0.46 → 0.0.50

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,61 @@
1
+ module Onering
2
+ module CLI
3
+ module Report
4
+ def self.configure(global={})
5
+ @api = (Onering::CLI.connect(global.merge({
6
+ :autoconnect => false
7
+ })) rescue nil)
8
+ @opts = ::Trollop::options do
9
+ banner <<-EOS
10
+ Generate a system report that can be saved or submitted to a Onering server
11
+
12
+ Usage:
13
+ onering [global] report [options]
14
+
15
+ Options:
16
+ EOS
17
+ opt :id, "Override the autodetected Hardware ID for this node", :short => '-I', :type => :string
18
+ opt :fields, "Set the named FIELD to equal VALUE in the format FIELD=VALUE. Can be specified multiple times", :short => '-o', :type => :string, :multi => true
19
+ opt :save, "Save the report output to the configured Onering server"
20
+ end
21
+
22
+ # initialize report generator with user options
23
+ Onering::Reporter.setup({
24
+ :id => @opts[:id]
25
+ }.compact)
26
+ end
27
+
28
+ def self.run(args)
29
+ report = Onering::Reporter.report().stringify_keys()
30
+
31
+ # pull report overrides from the config file
32
+ @api.opt('reporter.fields',{}).each do |field, value|
33
+ if value.is_a?(Hash)
34
+ value.coalesce(field, nil, '.').each do |k,v|
35
+ report = report.set(k, v)
36
+ end
37
+ else
38
+ report = report.set(field, value)
39
+ end
40
+ end
41
+
42
+ # pull overrides from CLI arguments
43
+ @opts[:fields].each do |field|
44
+ key, value = field.split('=', 2)
45
+ report = report.set(key, value)
46
+ end
47
+
48
+
49
+ # save if specified
50
+ if @opts[:save] === true
51
+ @api.connect()
52
+ @api.devices.save(report['id']) do
53
+ MultiJson.dump(report)
54
+ end
55
+ end
56
+
57
+ return report
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,56 @@
1
+ module Onering
2
+ module CLI
3
+ require 'yaml'
4
+ require 'multi_json'
5
+
6
+ def self.connect(cliargs)
7
+ @_args = cliargs
8
+
9
+ return Onering::API.new({
10
+ 'autoconnect' => cliargs[:autoconnect],
11
+ 'config' => {
12
+ 'url' => cliargs[:url],
13
+ 'path' => cliargs[:path],
14
+ 'authentication' => {
15
+ 'type' => (cliargs[:apikey_given] ? :token : nil),
16
+ 'keyfile' => (cliargs[:apikey] || cliargs[:sslkey])
17
+ }.compact
18
+ }.compact
19
+ }.compact)
20
+ end
21
+
22
+ def self.output(data, format)
23
+ return nil if @_args[:quiet]
24
+
25
+ case format
26
+ when 'text'
27
+ if data.is_a?(Hash)
28
+ data.coalesce.each do |k,v|
29
+ puts k.to_s+': '+v.to_s
30
+ end
31
+ else
32
+ [*data].each do |d|
33
+ if d.is_a?(Hash)
34
+ d.coalesce.each do |k,v|
35
+ puts k.to_s+': '+v.to_s
36
+ end
37
+ else
38
+ puts d unless d.empty?
39
+ end
40
+ end
41
+ end
42
+
43
+ when 'json'
44
+ puts MultiJson.dump(data)
45
+
46
+ when 'yaml'
47
+ puts YAML.dump(data)
48
+
49
+ else
50
+ raise "Unknown output format #{format.inspect}"
51
+ end
52
+
53
+ nil
54
+ end
55
+ end
56
+ end
@@ -1,38 +1,34 @@
1
-
2
1
  module Onering
3
- module API
4
- class Auth < Base
5
- class<<self
6
- def _check_type(type)
7
- raise "Invalid authentication module object '#{type}'" unless %w{
8
- users groups capabilities
9
- }.include?(type.to_s)
10
- end
2
+ class API
3
+ class Auth < API
4
+ def _check_type(type)
5
+ raise "Invalid authentication module object '#{type}'" unless %w{
6
+ users groups capabilities
7
+ }.include?(type.to_s)
8
+ end
11
9
 
12
- def get(type, id='current')
13
- _check_type(type)
14
- request("#{type}/#{id}")
15
- end
10
+ def show(type, id='current')
11
+ _check_type(type)
12
+ get("#{type}/#{id}").parsed_response
13
+ end
16
14
 
17
- def list(type, field='id', options={
18
- :unique => true,
19
- :sort => true,
20
- :filter => nil
21
- })
22
- _check_type(type)
23
- rv = request("#{type}/list").collect{|i| i[field.to_s] }
24
- rv = rv.uniq if options[:unique]
25
- rv = rv.sort if options[:sort]
26
- rv
27
- end
15
+ def list(type, field='id', options={
16
+ :unique => true,
17
+ :sort => true,
18
+ :filter => nil
19
+ })
20
+ _check_type(type)
21
+ rv = get("#{type}/list").parsed_response.collect{|i| i[field.to_s] }
22
+ rv = rv.uniq if options[:unique]
23
+ rv = rv.sort if options[:sort]
24
+ rv
25
+ end
28
26
 
29
- def save(type, id, data)
30
- _check_type(type)
31
- request("#{type}/#{id}", {
32
- :method => :post,
33
- :data => data
34
- })
35
- end
27
+ def save(type, id, data)
28
+ _check_type(type)
29
+ post("#{type}/#{id}", {
30
+ :body => data
31
+ }).parsed_response
36
32
  end
37
33
  end
38
34
  end
@@ -0,0 +1,66 @@
1
+ module Onering
2
+ class API
3
+ class AutomationRequests < API
4
+ def summary(fields)
5
+ get("/automation/requests/summary/#{[*fields].join('/')}").parsed_response
6
+ end
7
+
8
+ def find_by_status(status)
9
+ get("/automation/requests/status/#{status}").parsed_response
10
+ end
11
+
12
+ def show(id)
13
+ get("/automation/requests/#{id}").parsed_response
14
+ end
15
+
16
+ def requeue(id)
17
+ get("/automation/requests/#{id}/requeue").parsed_response
18
+ end
19
+
20
+ def flush_queue()
21
+ get("/automation/requests/flush").parsed_response
22
+ end
23
+
24
+ def requeue_all_failed()
25
+ get("/automation/requests/requeue").parsed_response
26
+ end
27
+ end
28
+
29
+
30
+ # -----------------------------------------------------------------------------
31
+ class AutomationJobs < API
32
+ def list()
33
+ get("/automation/jobs/list").parsed_response
34
+ end
35
+
36
+ def show(name)
37
+ get("/automation/jobs/#{name}").parsed_response
38
+ end
39
+
40
+ def requests_waiting(name)
41
+ get("/automation/jobs/#{name}/waiting").parsed_response
42
+ end
43
+
44
+ def run(name, options={}, &block)
45
+ if block_given?
46
+ post("/automation/jobs/#{name}/run", {
47
+ :query => options
48
+ }, &block).parsed_response
49
+ else
50
+ get("/automation/jobs/#{name}/run", {
51
+ :query => options
52
+ }).parsed_response
53
+ end
54
+ end
55
+ end
56
+
57
+ # -----------------------------------------------------------------------------
58
+ class AutomationTasks < API
59
+ def run(name, options={})
60
+ get("/automation/tasks/#{name}/run", {
61
+ :query => options
62
+ }).parsed_response
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,47 +1,47 @@
1
-
2
1
  module Onering
3
- module API
4
- class Devices < Base
5
- class<<self
6
- def get(id)
7
- request("devices/#{id}")
8
- end
2
+ class API
3
+ class Devices < API
4
+ def show(id)
5
+ get("/devices/#{id}").parsed_response
6
+ end
9
7
 
10
- def get_field(id, field)
11
- request("devices/#{id}/get/#{field}")
12
- end
8
+ def get_field(id, field)
9
+ get("/devices/#{id}/get/#{field}").response.body
10
+ end
13
11
 
14
- def set_field(id, field, value)
15
- request("devices/#{id}/set/#{field}/#{value}")
16
- end
12
+ def set_field(id, field, value)
13
+ get("/devices/#{id}/set/#{field}/#{value}").response.body
14
+ end
17
15
 
18
- def list(field, options={
19
- :unique => true,
20
- :sort => true,
21
- :filter => nil
22
- })
23
- qs = {
24
- :q => make_filter(options[:filter])
25
- } if options[:filter]
26
-
27
- rv = request("devices/list/#{field}", {
28
- :fields => qs
29
- })
16
+ def list(field, options={
17
+ :unique => true,
18
+ :sort => true,
19
+ :filter => nil
20
+ })
21
+ qs = {
22
+ :q => make_filter(options[:filter])
23
+ } if options[:filter]
30
24
 
31
- rv = rv.uniq if options[:unique]
32
- rv = rv.sort if options[:sort]
25
+ rv = get("/devices/list/#{field}", {
26
+ :query => qs
27
+ }).parsed_response
33
28
 
34
- rv
35
- end
29
+ rv = rv.uniq if options[:unique]
30
+ rv = rv.sort if options[:sort]
36
31
 
37
- def find(filter, options={})
38
- request("devices/find/#{make_filter(filter)}")
39
- end
32
+ return rv
33
+ end
34
+
35
+ def find(filter, options={})
36
+ get("/devices/find/#{make_filter(filter)}").parsed_response
37
+ end
40
38
 
41
- def save(id, data)
42
- request("devices/#{id}", {
43
- :method => :post,
44
- :data => data
39
+ def save(id, data=nil, &block)
40
+ if block_given?
41
+ post("/devices/#{id}", {}, &block)
42
+ else
43
+ post("/devices/#{id}", {
44
+ :body => data
45
45
  })
46
46
  end
47
47
  end
@@ -22,6 +22,8 @@ module Onering
22
22
  ]
23
23
 
24
24
  class<<self
25
+ include Onering::Util
26
+
25
27
  attr_reader :facter_path
26
28
 
27
29
  def setup(config={})
@@ -50,15 +52,6 @@ module Onering
50
52
  end
51
53
  end
52
54
 
53
-
54
- def fact(name, default=nil)
55
- if defined?(Facter)
56
- return (Facter.value(name) or default)
57
- end
58
-
59
- return nil
60
- end
61
-
62
55
  def load_plugins
63
56
  # load plugins from @path
64
57
  @path.compact.each do |root|
@@ -103,8 +96,8 @@ module Onering
103
96
  @_report[:properties][:metrics].set(name, value) if value
104
97
  end
105
98
 
106
- def report
107
- @id = (@options[:id] || (IO.read('/etc/hardware.id').to_s.nil_empty rescue nil))
99
+ def report()
100
+ @id = (@options[:id] || Onering::Util.fact('hardwareid', nil))
108
101
 
109
102
  if not @id.nil?
110
103
  hostname = (Facter.value('fqdn') rescue %x{hostname -f}.strip.chomp)
@@ -122,12 +115,12 @@ module Onering
122
115
  # loads plugins and populates @_report
123
116
  load_plugins
124
117
 
125
- return @_report
118
+ return @_report.stringify_keys()
126
119
  else
127
120
  raise "Cannot generate report without a hardware ID"
128
121
  end
129
122
 
130
- nil
123
+ {}
131
124
  end
132
125
  end
133
126
  end
data/lib/onering/util.rb CHANGED
@@ -7,8 +7,53 @@ module Onering
7
7
  end
8
8
  end
9
9
 
10
+ extend self
10
11
 
11
- def self.gem_path(name)
12
+
13
+ HTTP_STATUS_CODES = {
14
+ 400 => 'Bad Request',
15
+ 401 => 'Unauthorized',
16
+ 402 => 'Payment Required',
17
+ 403 => 'Forbidden',
18
+ 404 => 'Not Found',
19
+ 405 => 'Method Not Allowed',
20
+ 406 => 'Not Acceptable',
21
+ 407 => 'Proxy Authentication Required',
22
+ 408 => 'Request Timeout',
23
+ 409 => 'Conflict',
24
+ 410 => 'Gone',
25
+ 411 => 'Length Required',
26
+ 412 => 'Precondition Failed',
27
+ 413 => 'Request Entity Too Large',
28
+ 414 => 'Request-URI Too Long',
29
+ 415 => 'Unsupported Media Type',
30
+ 416 => 'Requested Range Not Satisfiable',
31
+ 417 => 'Expectation Failed',
32
+ 418 => 'I\'m a Teapot',
33
+ 420 => 'Enhance Your Calm',
34
+ 422 => 'Unprocessable Entity',
35
+ 423 => 'Locked',
36
+ 424 => 'Failed Dependency',
37
+ 426 => 'Upgrade Required',
38
+ 428 => 'Precondition Required',
39
+ 429 => 'Too Many Requests',
40
+ 431 => 'Request Header Fields Too Large',
41
+ 444 => 'No Response',
42
+ 451 => 'Unavailable For Legal Reasons',
43
+
44
+ 500 => 'Internal Server Error',
45
+ 501 => 'Not Implemented',
46
+ 502 => 'Bad Gateway',
47
+ 503 => 'Service Unavailable',
48
+ 504 => 'Gateway Timeout',
49
+ 505 => 'HTTP Version Not Supported',
50
+ 508 => 'Loop Detected',
51
+ 509 => 'Bandwidth Limit Exceeded',
52
+ 510 => 'Not Extended',
53
+ 511 => 'Network Authentication Required'
54
+ }
55
+
56
+ def gem_path(name)
12
57
  if Gem::Specification.respond_to?(:find_by_name)
13
58
  return Gem::Specification.find_by_name(name).gem_dir
14
59
  else
@@ -17,9 +62,54 @@ module Onering
17
62
  }.last.full_gem_path
18
63
  end
19
64
  end
65
+
66
+ def fact(name, default=nil)
67
+ name = name.to_s
68
+
69
+ if defined?(Facter)
70
+ fact = Facter.value(name)
71
+
72
+ # short circuit nil responses
73
+ return default if fact.nil?
74
+
75
+ # if we are asking for a nested object...
76
+ if name.include?('.')
77
+ # ...and the response IS an object...
78
+ if fact.is_a?(Hash)
79
+ # remove the first part and return the rest
80
+ name = name.sub(/^[^\.]+\./,'')
81
+ return fact.get(name, default)
82
+ else
83
+ # not an object, return default
84
+ return default
85
+ end
86
+ else
87
+ # this is a simple request, return the fact
88
+ return fact
89
+ end
90
+ end
91
+
92
+ return default
93
+ end
94
+
95
+ def make_filter(filter)
96
+ filter = filter.collect{|k,v| "#{k}/#{v}" } if filter.is_a?(Hash)
97
+ filter = filter.collect{|i| i.sub(':','/') }.join("/") if filter.is_a?(Array)
98
+ return filter
99
+ end
100
+
101
+ def http_status(code)
102
+ return (HTTP_STATUS_CODES[code.to_i] || nil)
103
+ end
20
104
  end
21
105
  end
22
106
 
23
107
  class String
24
108
  include Onering::Util::String
109
+ end
110
+
111
+ class Module
112
+ def submodules
113
+ constants.collect {|const_name| const_get(const_name)}.select {|const| const.class == Module}
114
+ end
25
115
  end
data/lib/onering.rb CHANGED
@@ -3,4 +3,11 @@ require 'onering/util'
3
3
  require 'onering/api'
4
4
  require 'onering/plugins/devices'
5
5
  require 'onering/plugins/authentication'
6
+ require 'onering/plugins/automation'
6
7
  require 'onering/plugins/reporter'
8
+ require 'onering/cli'
9
+ require 'onering/cli/call'
10
+ require 'onering/cli/fact'
11
+ require 'onering/cli/devices'
12
+ require 'onering/cli/automation'
13
+ require 'onering/cli/reporter'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: onering-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.46
4
+ version: 0.0.50
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2013-01-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: facter
16
- requirement: &21024540 !ruby/object:Gem::Requirement
16
+ requirement: &6690160 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *21024540
24
+ version_requirements: *6690160
25
25
  - !ruby/object:Gem::Dependency
26
- name: subcommander
27
- requirement: &21022680 !ruby/object:Gem::Requirement
26
+ name: deep_merge
27
+ requirement: &6689220 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *21022680
35
+ version_requirements: *6689220
36
36
  - !ruby/object:Gem::Dependency
37
- name: deep_merge
38
- requirement: &21020640 !ruby/object:Gem::Requirement
37
+ name: addressable
38
+ requirement: &6688340 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *21020640
46
+ version_requirements: *6688340
47
47
  - !ruby/object:Gem::Dependency
48
- name: addressable
49
- requirement: &20995240 !ruby/object:Gem::Requirement
48
+ name: httparty
49
+ requirement: &6687680 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *20995240
57
+ version_requirements: *6687680
58
58
  - !ruby/object:Gem::Dependency
59
- name: rest-client
60
- requirement: &20993960 !ruby/object:Gem::Requirement
59
+ name: hashlib
60
+ requirement: &6686980 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *20993960
68
+ version_requirements: *6686980
69
69
  - !ruby/object:Gem::Dependency
70
- name: hashlib
71
- requirement: &20992780 !ruby/object:Gem::Requirement
70
+ name: multi_json
71
+ requirement: &6578580 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *20992780
79
+ version_requirements: *6578580
80
80
  - !ruby/object:Gem::Dependency
81
- name: multi_json
82
- requirement: &20990720 !ruby/object:Gem::Requirement
81
+ name: rainbow
82
+ requirement: &6577580 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *20990720
90
+ version_requirements: *6577580
91
91
  - !ruby/object:Gem::Dependency
92
- name: rainbow
93
- requirement: &20989400 !ruby/object:Gem::Requirement
92
+ name: trollop
93
+ requirement: &6576960 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: '0'
99
99
  type: :runtime
100
100
  prerelease: false
101
- version_requirements: *20989400
101
+ version_requirements: *6576960
102
102
  description: A Ruby wrapper for Onering
103
103
  email: ghetzel@outbrain.com
104
104
  executables:
@@ -109,8 +109,15 @@ files:
109
109
  - lib/onering.rb
110
110
  - lib/onering/util.rb
111
111
  - lib/onering/api.rb
112
+ - lib/onering/cli.rb
113
+ - lib/onering/cli/fact.rb
114
+ - lib/onering/cli/call.rb
115
+ - lib/onering/cli/devices.rb
116
+ - lib/onering/cli/automation.rb
117
+ - lib/onering/cli/reporter.rb
112
118
  - lib/onering/plugins/devices.rb
113
119
  - lib/onering/plugins/authentication.rb
120
+ - lib/onering/plugins/automation.rb
114
121
  - lib/onering/plugins/reporter.rb
115
122
  - bin/onering
116
123
  homepage: https://github.com/outbrain/onering-ruby