onering-client 0.0.10 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -26,27 +26,79 @@ def print_format(data, format=nil)
26
26
  else
27
27
  puts data.to_s
28
28
  end
29
-
29
+
30
30
  else
31
31
  puts YAML.dump(data)
32
32
  end
33
33
  end
34
34
 
35
- subcommander.version = Gem.loaded_specs['onering-client'].version.to_s
36
- subcommander.desc = Gem.loaded_specs['onering-client'].description
35
+ subcommander.version = ::Gem.loaded_specs['onering-client'].version.to_s
36
+ subcommander.desc = ::Gem.loaded_specs['onering-client'].description
37
37
 
38
38
  #subcommander.opt :server, '-s', '--server', 'Specify the Onering server URL'
39
39
 
40
40
  subcommand :devices, "Operations related to Onering's assets database" do |devices|
41
41
  api = Onering::API::Devices
42
- api.connect
42
+ api.connect ENV['ONERING_URL']
43
+
44
+ def _field(action, field, value, opts={})
45
+ rv = []
46
+ ids = []
47
+
48
+ # append IDs from filter
49
+ ids += Onering::API::Devices.list('id', {
50
+ :filter => opts[:filter]
51
+ }) if opts[:filter]
52
+
53
+ # add specific ID
54
+ ids << opts[:id] if opts[:id]
55
+
56
+ ids.each do |id|
57
+ case action
58
+ when :get
59
+ rv << Onering::API::Devices.get_field(id, field)
60
+ when :set
61
+ rv << Onering::API::Devices.set_field(id, field, value)
62
+ end
63
+ end
64
+
65
+ rv
66
+ end
67
+
68
+ # SHOW
69
+ devices.subcommand :show, "Print out a single node by ID" do |sc|
70
+ sc.usage = "onering devices show ID"
71
+
72
+ sc.exec do
73
+ id = sc[:args].first
74
+ print_format(api.get(id))
75
+ end
76
+ end
77
+
78
+ # GET [FIELD]
79
+ devices.subcommand :get, "Get a named field from one or more devices" do |sc|
80
+ sc.usage = "onering devices get FIELD"
81
+ sc.opt :filter, '-f', '--filter FILTER', "A urlquery filter string"
82
+ sc.opt :as_txt, '-t', '--as-text', "Return the results as text"
83
+ sc.opt :id, '-i', '--id ID', "A specific node ID"
84
+
85
+
86
+ sc.exec do
87
+ rv = _field(:get, sc[:args].first, nil, sc)
88
+ print_format(rv, (sc[:as_txt] ? :text : nil))
89
+ end
90
+ end
43
91
 
44
- # GET
45
- devices.subcommand :get, "Get a single node by ID" do |sc|
46
- sc.usage = "onering devices get ID"
92
+ # SET [FIELD]
93
+ devices.subcommand :set, "Set a named field for one or more devices" do |sc|
94
+ sc.usage = "onering devices set FIELD VALUE"
95
+ sc.opt :filter, '-f', '--filter FILTER', "A urlquery filter string"
96
+ sc.opt :as_txt, '-t', '--as-text', "Return the results as text"
97
+ sc.opt :id, '-i', '--id ID', "A specific node ID"
47
98
 
48
- sc.exec do
49
- print_format(api.get(sc[:args].first))
99
+ sc.exec do
100
+ rv = _field(:set, sc[:args].first, sc[:args].last, sc)
101
+ print_format(rv, (sc[:as_txt] ? :text : nil))
50
102
  end
51
103
  end
52
104
 
@@ -56,7 +108,7 @@ subcommand :devices, "Operations related to Onering's assets database" do |devic
56
108
  sc.opt :filter, '-f', '--filter FILTER', "A urlquery filter string"
57
109
  sc.opt :as_txt, '-t', '--as-text', "Return the results as text"
58
110
 
59
- sc.exec do
111
+ sc.exec do
60
112
  field = sc[:args].first
61
113
  filter = sc[:filter]
62
114
 
@@ -71,10 +123,29 @@ subcommand :devices, "Operations related to Onering's assets database" do |devic
71
123
  sc.arity = 1
72
124
  sc.usage = "onering devices find FILTER"
73
125
 
74
- sc.exec do
126
+ sc.exec do
75
127
  print_format(api.find(sc[:args].first))
76
128
  end
77
129
  end
130
+
131
+ # SAVE
132
+ devices.subcommand :save, "Creates or updates a new device in Onering, reading a JSON document from standard input" do |sc|
133
+ sc.usage = "cat device.json | onering devices save [ID]"
134
+
135
+ sc.exec do
136
+ unless STDIN.tty?
137
+ begin
138
+ json = ::JSON.load(STDIN.read)
139
+ raise "Input document must specify an ID" if sc[:args].empty? and not json['id']
140
+
141
+ print_format(api.save((sc[:args].first || json['id']), json))
142
+ rescue Exception => e
143
+ STDERR.puts "#{e.class.name}: #{e.message}"
144
+ exit 1
145
+ end
146
+ end
147
+ end
148
+ end
78
149
  end
79
150
 
80
151
 
@@ -2,26 +2,30 @@ require 'net/http'
2
2
  require 'uri'
3
3
  require 'json'
4
4
  require 'yaml'
5
+ require 'addressable/uri'
5
6
 
6
7
  module Onering
7
8
  module API
8
9
  module Errors
9
10
  class NotConnected < Exception; end
10
11
  class ClientError < Exception; end
12
+ class ServerError < Exception; end
11
13
  end
12
14
 
13
15
  class Base
16
+ DEFAULT_BASE="http://onering"
17
+ DEFAULT_PATH="/api"
18
+ DEFAULT_OPTIONS={}
19
+
14
20
  class<<self
15
- DEFAULT_URI="http://onering/api"
16
- DEFAULT_OPTIONS={}
17
21
 
18
22
  def connect(host=nil)
19
23
  if host.is_a?(URI)
20
24
  @_uri = host
21
25
  elsif host.is_a?(String)
22
- @_uri = URI.parse(host)
26
+ @_uri = Addressable::URI.parse("#{host}/#{DEFAULT_PATH}")
23
27
  else
24
- @_uri = URI.parse(DEFAULT_URI)
28
+ @_uri = Addressable::URI.parse("#{DEFAULT_BASE}/#{DEFAULT_PATH}")
25
29
  end
26
30
 
27
31
 
@@ -34,17 +38,17 @@ module Onering
34
38
  options = DEFAULT_OPTIONS.merge(options)
35
39
  request = nil
36
40
 
37
- qs = options[:fields].collect{|k,v| "#{k}=#{v}" }.join("&") if options[:fields]
38
- qs = nil if qs and qs.empty?
39
- endpoint = [endpoint, qs].compact.join('?')
40
- uri = URI.parse("#{@_uri.to_s}/#{endpoint}")
41
+ uri = Addressable::URI.parse("#{@_uri.to_s}/#{endpoint}")
42
+ uri.query_values = options[:fields] if options[:fields]
41
43
 
42
44
  raise Errors::NotConnected unless @_http
43
45
 
46
+ #STDERR.puts "DEBUG: Request #{options[:method].to_s.upcase} #{uri.normalize.to_s}"
47
+
44
48
  case options[:method]
45
49
  when :post
46
50
  request = Net::HTTP::Post.new(uri.request_uri)
47
- request.body = JSON.dump(options[:data]) if options[:data]
51
+ request.body = options[:data].to_json if options[:data]
48
52
 
49
53
  when :delete
50
54
  request = Net::HTTP::Delete.new(uri.request_uri)
@@ -63,9 +67,17 @@ module Onering
63
67
  msg = "#{rv['errors']['type']}: #{rv['errors']['message']}"
64
68
  end
65
69
 
66
- raise ClientError.new(msg)
70
+ if response.code.to_i >= 500
71
+ raise Errors::ServerError.new("HTTP #{response.code}: #{msg}")
72
+ else
73
+ raise Errors::ClientError.new("HTTP #{response.code}: #{msg}")
74
+ end
67
75
  else
68
- rv = JSON.load(response.body)
76
+ if response['Content-Type'] == 'application/json'
77
+ rv = JSON.load(response.body)
78
+ else
79
+ rv = response.body
80
+ end
69
81
  end
70
82
 
71
83
  rv
@@ -11,6 +11,14 @@ module Onering
11
11
  request("devices/#{id}")
12
12
  end
13
13
 
14
+ def get_field(id, field)
15
+ request("devices/#{id}/get/#{field}")
16
+ end
17
+
18
+ def set_field(id, field, value)
19
+ request("devices/#{id}/set/#{field}/#{value}")
20
+ end
21
+
14
22
  def list(field, options={
15
23
  :unique => true,
16
24
  :sort => true,
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: onering-client
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 10
10
- version: 0.0.10
9
+ - 15
10
+ version: 0.0.15
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gary Hetzel
@@ -16,8 +16,35 @@ bindir: bin
16
16
  cert_chain: []
17
17
 
18
18
  date: 2013-01-29 00:00:00 Z
19
- dependencies: []
20
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: subcommander
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: addressable
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
21
48
  description: A Ruby wrapper for Onering
22
49
  email: ghetzel@outbrain.com
23
50
  executables: