hieracles 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a6b5269d88007785d1a82bc4ea5d9a6575206923
4
- data.tar.gz: 3771f9302b9061157874ab0bf715f6c1588525ef
3
+ metadata.gz: 576b1abbe8d06fcf61896855b5474ed2d549e277
4
+ data.tar.gz: 79022f2d38d33472e1e629724ebc4882c7718ba3
5
5
  SHA512:
6
- metadata.gz: e475ba6285c981327d5dd5a662bc8ed27d82606c3a78c383f5f2a9e0cbd8d85666bd8f3a2641ad0c2bd883f960ac7892fba3760d91d38e8e008f8d6f7aec7d4d
7
- data.tar.gz: 8f554bbede7cf6fb3dceca5cf6f18c62defd5ee89b1b20df4a9403014044713b53f931e0e38c85cebe03fa990f67b0ab0ac3c01e41291bced3b9eea89b229303
6
+ metadata.gz: fd35c1ac42aca8724d507904387fb8bbd9543977482bd47e12e8e6301ec09e31ad655521b25904cd99c155caa5bb1ad1799e4e2ee3e4008fdc76f5582eb01139
7
+ data.tar.gz: 8a0528fd874dc417140713ac28858f131f0d858a843e4df1d07861934e7ac57d18061201ba360876333f986457be88f1365c94562d50b5d50331162b77cedc81
data/CHANGELOG.md CHANGED
@@ -1,6 +1,17 @@
1
1
  Hieracles Changelog
2
2
  =======================
3
3
 
4
+ ### 0.3.0 - 2015-12-16
5
+ - added json output as an option to ppdb
6
+ - added some more ppdb commands
7
+ - ppdb resources <queries>
8
+ - ppdb same
9
+ - ppdb factnames
10
+ - updated manpage for ppdb with proper documentation
11
+ - prepare a queries transformation class to
12
+ match puppetdb weird query language with a more human one
13
+ - updated ppdb zsh completion
14
+
4
15
  ### 0.2.2 - 2015-12-11
5
16
  - remove support for ruby 1.9.3
6
17
  because of the mime-type gem
data/bin/ppdb CHANGED
@@ -12,31 +12,40 @@ if opt.options.has_key? :version
12
12
  exit(0)
13
13
  end
14
14
 
15
- unless opt.payload[1]
15
+ unless opt.payload[0]
16
16
  puts Hieracles::Options::Ppdb.usage
17
17
  exit(1)
18
18
  end
19
19
 
20
- command = "#{opt.payload[0]}_#{opt.payload[1]}"
21
- args = opt.payload[2..-1] || []
20
+ endpoint = opt.payload[0]
22
21
 
22
+ if Hieracles::Puppetdb::Request.method_defined? endpoint
23
+ command = endpoint
24
+ args = opt.payload[1..-1] || []
25
+ elsif Hieracles::Puppetdb::Request.method_defined? "#{opt.payload[0]}_#{opt.payload[1]}"
26
+ command = "#{opt.payload[0]}_#{opt.payload[1]}"
27
+ args = opt.payload[2..-1] || []
28
+ else
29
+ puts "*** Unknown command: #{command}"
30
+ puts Hieracles::Options::Ppdb.usage
31
+ exit(1)
32
+ end
33
+
23
34
  Hieracles::Config.load opt.options
24
35
 
25
- if Hieracles::Puppetdb::Request.method_defined? command
26
- request = Hieracles::Puppetdb::Request.new Hieracles::Config.puppetdb
27
- meth = request.method(command.to_sym)
28
- required = request.method(command.to_sym).parameters.select { |arg| arg[0] == :req }.map { |arg| arg[1] }
29
- if args.length < required.length
30
- args = required.join(', ')
31
- puts "*** The #{command} method requires arguments: #{args}"
32
- exit(1)
36
+ request = Hieracles::Puppetdb::Request.new Hieracles::Config.puppetdb
37
+ meth = request.method(command.to_sym)
38
+ required = request.method(command.to_sym).parameters.select { |arg| arg[0] == :req }.map { |arg| arg[1] }
39
+ if args.length < required.length
40
+ args = required.join(', ')
41
+ puts "*** The #{command} method requires arguments: #{args}"
42
+ exit(1)
43
+ else
44
+ if Hieracles::Config.format == 'Json'
45
+ format = Hieracles::Formats::Json.new(nil)
33
46
  else
34
47
  format = Hieracles::Formats::Console.new(nil)
35
- resp = meth.call(*args)
36
- puts format.build_list(resp.data, resp.notifications, [])
37
48
  end
38
- else
39
- puts "*** Unknown command: #{command}"
40
- puts Hieracles::Options::Ppdb.usage
41
- exit(1)
49
+ resp = meth.call(*args)
50
+ puts format.build_list(resp.data, resp.notifications, [])
42
51
  end
@@ -35,17 +35,23 @@ module Hieracles
35
35
 
36
36
  def build_list(hash, notifications, filter)
37
37
  back = ''
38
- back << build_notifications(notifications) if notifications
39
- if filter[0]
40
- hash.select! { |k, v| Regexp.new(filter[0]).match(k.to_s) }
41
- end
42
- length = max_key_length(hash) + 2
43
- title = format(COLORS[8], "%-#{length}s")
44
- hash.each do |k, v|
45
- if v.class.name == 'Hash' || v.class.name == 'Array'
46
- v = v.ai({ indent: 10, raw: true}).strip
38
+ if hash.class.name == 'Array'
39
+ hash.each do |v|
40
+ back << "#{v}\n"
41
+ end
42
+ else
43
+ back << build_notifications(notifications) if notifications
44
+ if filter[0]
45
+ hash.select! { |k, v| Regexp.new(filter[0]).match(k.to_s) }
46
+ end
47
+ length = max_key_length(hash) + 2
48
+ title = format(COLORS[8], "%-#{length}s")
49
+ hash.each do |k, v|
50
+ if v.class.name == 'Hash' || v.class.name == 'Array'
51
+ v = v.ai({ indent: 10, raw: true}).strip
52
+ end
53
+ back << format("#{title} %s\n", k, v)
47
54
  end
48
- back << format("#{title} %s\n", k, v)
49
55
  end
50
56
  back
51
57
  end
@@ -33,6 +33,13 @@ module Hieracles
33
33
  @node.params(false).merge(alerts).to_json
34
34
  end
35
35
 
36
+ def build_list(hash, notifications, filter)
37
+ {
38
+ 'notifications' => notifications,
39
+ 'payload' => hash
40
+ }.to_json
41
+ end
42
+
36
43
  private
37
44
 
38
45
  def alerts
@@ -9,6 +9,10 @@ module Hieracles
9
9
  version: {
10
10
  has_arg: false,
11
11
  aliases: ['v', 'version']
12
+ },
13
+ format: {
14
+ has_arg: true,
15
+ aliases: ['f', 'format']
12
16
  }
13
17
  }
14
18
  end
@@ -16,13 +20,20 @@ module Hieracles
16
20
  def self.usage
17
21
  return <<-END
18
22
 
19
- Usage: ppdb <endpoint> <command> [extra_args]
23
+ Usage: ppdb <command> [extra_args]
20
24
 
21
25
  Available commands:
22
26
  node info <fqdn>
23
27
  node facts <fqdn>
24
28
  node resources <fqdn>
25
-
29
+ facts <name> <value>
30
+ same <name> <fqdn>
31
+ factnames
32
+ res[ources] <query>
33
+ query following the form:
34
+ type=sometype title=what
35
+ type=sometype or type=another
36
+ type~someregexp type!~excluded
26
37
  END
27
38
  end
28
39
 
@@ -24,7 +24,7 @@ module Hieracles
24
24
  end
25
25
  end
26
26
 
27
- def request(endpoint, method = 'get', query = nil, opts = {})
27
+ def request(endpoint, query = nil, method = 'get', opts = {})
28
28
  ret = send("#{method}_request".to_sym, endpoint, query, opts)
29
29
  if ret.code.to_s() =~ /^[4|5]/ or ret.parsed_response.length < 1
30
30
  notifications = [ Hieracles::Notification.new('puppetdb', 'No match.', 'error') ]
@@ -34,7 +34,6 @@ module Hieracles
34
34
  if total.nil?
35
35
  total = ret.parsed_response.length
36
36
  end
37
-
38
37
  Response.new(ret.parsed_response, total)
39
38
  end
40
39
  end
@@ -51,7 +50,7 @@ module Hieracles
51
50
  filtered_opts[k.to_s.sub("_", "-")] = v
52
51
  end
53
52
  end
54
- puts path ; puts filtered_opts ; exit(0)
53
+ #puts path ; puts filtered_opts ; exit(0)
55
54
  self.class.get(path, query: filtered_opts)
56
55
  else
57
56
  self.class.get(path)
@@ -2,78 +2,67 @@ module Hieracles
2
2
  module Puppetdb
3
3
  class Query
4
4
 
5
+ attr_reader :elements
6
+
5
7
  def initialize(elements)
6
8
  @elements = parse(elements)
7
9
  end
8
10
 
9
11
  def parse(elements)
10
- items = []
11
- index = 0
12
- if elements.length > 1
13
- elements.each do |e|
14
- puts items.inspect
15
- if e == 'or'
16
- index++
17
- continue
18
- end
19
- if /(.*)(>|<|=|!=|~)(.*)/.match e
20
- items[index] ||= []
21
- items[index] << [$2, $1, $3]
22
- end
23
- end
24
- else
25
- if /(.*)(>|<|=|!=|~)(.*)/.match elements[0]
26
- items = [$2, $1, $3]
27
- end
12
+ if number_or(elements) > 0
13
+ elements = build_or(elements)
28
14
  end
29
- items
15
+ build_and elements
30
16
  end
31
17
 
32
- def output
33
- back = []
34
- if @elements.length > 1
35
- back << 'or'
36
- @elements.each do |e|
37
- back << build_and(e)
38
- end
39
- else
40
- @elements.each do |e|
41
- back << build_and(e)
18
+ def build_and(arrays)
19
+ back = arrays.reduce([]) do |a, v|
20
+ if v.class.name == 'Array'
21
+ if v.length > 1
22
+ a << ['and'] + v.map { |e| expression(e) }
23
+ else
24
+ e = expression(v[0])
25
+ a << e if e
26
+ end
27
+ elsif v == 'or'
28
+ a << 'or'
29
+ else
30
+ e = expression(v)
31
+ a << e if e
42
32
  end
33
+ a
34
+ end
35
+ if back.length == 1 and back[0].class.name == 'Array'
36
+ back = back[0]
37
+ elsif back[0].class.name == 'Array' and back.length > 1
38
+ back.unshift('and')
43
39
  end
44
40
  back
45
41
  end
46
42
 
47
- def build_and(arrays)
48
- if arrays.length > 1
49
- ['and', arrays]
50
- else
51
- arrays
43
+ def build_or(arrays)
44
+ back = ['or']
45
+ (0..number_or(arrays)-1).each do |a|
46
+ back << arrays.slice!(0..arrays.index('or')-1)
47
+ arrays.shift
52
48
  end
49
+ back << arrays
53
50
  end
54
51
 
55
- def defined?
56
- @elements.count > 0
57
- end
58
-
59
- def match(item)
60
- @elements.each do |e|
61
- matched = false
62
- e.each do |a|
63
- case a[0]
64
- when '='
65
-
66
- when '!='
67
- when '<'
68
- when '>'
69
- when '!'
70
- else
71
- end
52
+ def expression(e)
53
+ if /([^!]*)(!)?(>|<|=|~)(.*)/.match e
54
+ if $2
55
+ ['not', [$3, $1, $4]]
56
+ else
57
+ [$3, $1, $4]
72
58
  end
73
- return true if matched
74
59
  end
75
60
  end
76
61
 
62
+ def number_or(a)
63
+ a.select { |i| i == 'or' }.length
64
+ end
65
+
77
66
  end
78
67
  end
79
68
  end
@@ -27,17 +27,54 @@ module Hieracles
27
27
  def node_resources(fqdn, *args)
28
28
  resp = @client.request("nodes/#{fqdn}/resources")
29
29
  field = args.shift
30
- resp.data = resp.data.reduce({}) do |a, d|
31
- if !field || Regexp.new(field).match(d['title'])
32
- a[d['title']] = d
30
+ make_hashed resp
31
+ end
32
+ alias_method :node_res, :node_resources
33
+
34
+ def facts(label, value)
35
+ resp = @client.request("facts/#{label}/#{value}")
36
+ extract_names resp
37
+ end
38
+
39
+ def same(name, fqdn)
40
+ r = @client.request("nodes/#{fqdn}/facts/#{name}")
41
+ if r.data.length > 0
42
+ value = r.data[0]['value']
43
+ facts name, value
44
+ else
45
+ r
46
+ end
47
+ end
48
+
49
+ def factnames()
50
+ @client.request("fact-names")
51
+ end
52
+
53
+ def resources(*args)
54
+ query = Query.new args
55
+ make_hashed @client.request("resources", query.elements)
56
+ end
57
+ alias_method :res, :resources
58
+
59
+ private
60
+
61
+ def extract_names(resp, label = 'certname')
62
+ resp.data = resp.data.reduce([]) do |a, d|
63
+ a << d[label]
64
+ a
65
+ end.sort
66
+ resp
67
+ end
68
+
69
+ def make_hashed(resp, label = 'title', filter = nil)
70
+ resp.data = resp.data.reduce({}) do |a, d|
71
+ if !filter || Regexp.new(filter).match(d[label])
72
+ a[d[label]] = d
33
73
  end
34
74
  a
35
75
  end
36
76
  resp
37
77
  end
38
- alias_method :node_res, :node_resources
39
-
40
-
41
78
 
42
79
  end
43
80
  end
data/ppdb.1 CHANGED
@@ -4,7 +4,6 @@
4
4
  ppdb \- Command line tool to query puppetdb
5
5
  .SH SYNOPSIS
6
6
  .B ppdb
7
- .I object
8
7
  .I command
9
8
  .B [
10
9
  .I options
@@ -29,17 +28,11 @@ of the PuppetDB API.
29
28
  Ref http://docs.puppetlabs.com/puppetdb/2.3/api/
30
29
  .PP
31
30
  .B ppdb
32
- takes at minimum 2 arguments, an object (or endpoint)
33
- and a subcommand, plus extra parameters depending the subcommand.
34
- .PP
35
- The object is like the endpoint in PuppetDB API, but we extend it
36
- to a different list of possible objects:
37
-
38
- .IP node 10
39
- Uses the nodes endpoint. It accepts the subcommands:
40
- .RS
31
+ takes a command, plus extra parameters depending the command.
41
32
 
42
- .IP info 10
33
+ .TP
34
+ .PD 0
35
+ .B node info \fR<fqdn>
43
36
  will display the equivalent of
44
37
  .I "GET /v3/nodes/<NODE>"
45
38
  and takes the node
@@ -60,7 +53,9 @@ in their label.
60
53
  .RE
61
54
  .RE
62
55
 
63
- .IP facts 10
56
+ .TP
57
+ .PD 0
58
+ .B node facts \fR<fqdn>
64
59
  will display the equivalent of
65
60
  .I "GET /v3/nodes/<NODE>/facts"
66
61
  and takes the node
@@ -82,7 +77,9 @@ in their label.
82
77
  .RE
83
78
  .RE
84
79
 
85
- .IP resources 10
80
+ .TP
81
+ .PD 0
82
+ .B node resources \fR<fqdn>
86
83
  will display the equivalent of
87
84
  .I "GET /v3/nodes/<NODE>/resources"
88
85
  and takes the node
@@ -108,6 +105,65 @@ in their label.
108
105
  .RE
109
106
  .RE
110
107
 
108
+ .RE
109
+
110
+ .TP
111
+ .PD 0
112
+ .B facts <name> <value>
113
+ will list all fqdn (aka. certnames) of the nodes having the <name>
114
+ fact set to <value>.
115
+ .RS
116
+ eq. ppdb facts puppet_environment dev
117
+ .RE
118
+
119
+ .TP
120
+ .PD 0
121
+ .B same <name> <fqdn>
122
+ will list all the fqdn having the same value for the fact <name> as
123
+ <fqdn> has.
124
+ .RS
125
+ eq. ppdb same farm node32.example.com
126
+ .RE
127
+
128
+ .TP
129
+ .PD 0
130
+ .B resources <queries>
131
+ .TP
132
+ .PD
133
+ .B res <queries>
134
+ will list the resources matching a given set of queries.
135
+ Queries are a combination of statements, with a label, an operator
136
+ and a value. You can use
137
+ .I or
138
+ to separate one or several statements. If there is no
139
+ .I or
140
+ indicated, the statements follow an
141
+ .I and
142
+ logic. All statements that don't contain an operator or match the
143
+ .I or
144
+ keyword are purely ignored (which makes possible to use the
145
+ .I and
146
+ keyword for mental stability purpose).
147
+
148
+ .RS
149
+ Operators can be >, <, =, ~ and can be prefixed by a ! to negate them.
150
+ .RS
151
+ eq. ppdb res type=Nagios_ghost and tag~api
152
+ .RE
153
+ .RS
154
+ eq. ppdb res tag~api title!~dev
155
+ .RE
156
+ .RS
157
+ eq. ppdb res tag~api or certname~api or title~api
158
+ .RE
159
+ .RE
160
+
161
+ .TP
162
+ .PD 0
163
+ .B factnames
164
+ will list all the factnames puppetdb knows about.
165
+ This may be a long list.
166
+
111
167
  .SH OPTIONS
112
168
 
113
169
  .TP
@@ -118,6 +174,15 @@ in their label.
118
174
  .B \-\-version
119
175
  outputs version.
120
176
 
177
+ .TP
178
+ .PD 0
179
+ .B \-f \fRformat
180
+ .TP
181
+ .PD
182
+ .B \-\-format \fRformat
183
+ outputs in the selected format. For now only the json format
184
+ is available as an alternative to the default console format.
185
+
121
186
 
122
187
  .SH FILES
123
188
  .I ~/.config/hieracles/config.yaml
@@ -26,7 +26,7 @@ describe Hieracles::Puppetdb::Client do
26
26
  describe '.request' do
27
27
  context 'with a GET request' do
28
28
  let(:client) { Hieracles::Puppetdb::Client.new Hash.new }
29
- let(:request) { client.request('endpoint', 'get')}
29
+ let(:request) { client.request('endpoint')}
30
30
  let(:response) { Hieracles::Puppetdb::Response.new(Hash.new, 0, Array.new) }
31
31
  before {
32
32
  resp = double
@@ -49,7 +49,7 @@ describe Hieracles::Puppetdb::Client do
49
49
  describe '.get_request' do
50
50
  let(:client) { Hieracles::Puppetdb::Client.new Hash.new }
51
51
  context 'without query' do
52
- let(:request) { client.request('endpoint', 'get')}
52
+ let(:request) { client.request('endpoint')}
53
53
  before {
54
54
  allow(client.class).
55
55
  to receive(:get).
@@ -2,18 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe Hieracles::Puppetdb::Query do
4
4
 
5
- describe '.new' do
6
- let(:elements) { [ 'something=value' ] }
7
- let(:query) { Hieracles::Puppetdb::Query.new elements }
8
- before {
9
- allow(query).
10
- to receive(:parse).
11
- with(elements).
12
- and_return(['=', 'something', 'value'])
13
- }
14
- it { expect(query.instance_variable_get(:@elements)).to eq ['=', 'something', 'value'] }
15
- end
16
-
17
5
  describe '.parse' do
18
6
  context 'with a single argument not matching an assignment' do
19
7
  let(:elements) { [ 'anything' ] }
@@ -29,11 +17,91 @@ describe Hieracles::Puppetdb::Query do
29
17
  end
30
18
  context 'with 2 arguments matching an assignment' do
31
19
  let(:elements) { [ 'something=value', 'another=else' ] }
32
- let(:expected) { [['=', 'something', 'value'], ['=', 'another', 'else']] }
20
+ let(:expected) { ['and', ['=', 'something', 'value'], ['=', 'another', 'else']] }
21
+ let(:query) { Hieracles::Puppetdb::Query.new elements }
22
+ it { expect(query.instance_variable_get(:@elements)).to eq expected }
23
+ end
24
+ context 'with 3 arguments but only 2 match assignment' do
25
+ let(:elements) { [ 'something=value', 'and', 'another=else' ] }
26
+ let(:expected) { ['and', ['=', 'something', 'value'], ['=', 'another', 'else']] }
27
+ let(:query) { Hieracles::Puppetdb::Query.new elements }
28
+ it { expect(query.instance_variable_get(:@elements)).to eq expected }
29
+ end
30
+ context 'with 2 arguments separated by a or' do
31
+ let(:elements) { [ 'something=value', 'or', 'another=else' ] }
32
+ let(:expected) { ['or', ['=', 'something', 'value'], ['=', 'another', 'else']] }
33
33
  let(:query) { Hieracles::Puppetdb::Query.new elements }
34
- #it { expect(query.instance_variable_get(:@elements)).to eq expected }
34
+ it { expect(query.instance_variable_get(:@elements)).to eq expected }
35
35
  end
36
+ context 'with 3 arguments including a or' do
37
+ let(:elements) { [ 'something=value', 'or', 'another=else', 'more=ever' ] }
38
+ let(:expected) {
39
+ [ 'or',
40
+ ['=', 'something', 'value'],
41
+ ['and', ['=', 'another', 'else'], ['=', 'more', 'ever']]
42
+ ]
43
+ }
44
+ let(:query) { Hieracles::Puppetdb::Query.new elements }
45
+ it { expect(query.instance_variable_get(:@elements)).to eq expected }
46
+ end
47
+ end
36
48
 
49
+ describe '.build_and' do
50
+ let(:query) { Hieracles::Puppetdb::Query.new [] }
51
+ context 'with no and' do
52
+ let(:array) { ["a=b"]}
53
+ let(:expected) { ['=', 'a', 'b'] }
54
+ it { expect(query.send(:build_and, array)).to eq expected }
55
+ end
56
+ context 'with a single and' do
57
+ let(:array) { ["a=b", "a=c"]}
58
+ let(:expected) { ['and', ['=', 'a', 'b'],['=', 'a', 'c']] }
59
+ it { expect(query.send(:build_and, array)).to eq expected }
60
+ end
61
+
62
+ end
63
+
64
+ describe '.build_or' do
65
+ let(:query) { Hieracles::Puppetdb::Query.new [] }
66
+ context 'with a single or' do
67
+ let(:array) { ["a=b", "or", "a=c"]}
68
+ let(:expected) { ['or', ['a=b'],['a=c']]}
69
+ it { expect(query.send(:build_or, array)).to eq expected }
70
+ end
71
+ context 'with a double or' do
72
+ let(:array) { ["a=b", "or", "a=c", "or", "a=d"]}
73
+ let(:expected) { ['or', ['a=b'],['a=c'],['a=d']]}
74
+ it { expect(query.send(:build_or, array)).to eq expected }
75
+ end
76
+ context 'with a double or and multiple ands' do
77
+ let(:array) { ["a=b", "a=x", "or", "a=c", "or", "a=d"]}
78
+ let(:expected) { ['or', ['a=b', 'a=x'],['a=c'],['a=d']]}
79
+ it { expect(query.send(:build_or, array)).to eq expected }
80
+ end
81
+ end
82
+
83
+ describe '.expression' do
84
+ let(:query) { Hieracles::Puppetdb::Query.new [] }
85
+ context 'with a = sign' do
86
+ let(:string) { 'a=b' }
87
+ let(:expected) { ['=', 'a', 'b']}
88
+ it { expect(query.send(:expression, string)).to eq expected }
89
+ end
90
+ context 'with a != sign' do
91
+ let(:string) { 'a!=b' }
92
+ let(:expected) { ['not', ['=', 'a', 'b']]}
93
+ it { expect(query.send(:expression, string)).to eq expected }
94
+ end
95
+ context 'with a ~ sign' do
96
+ let(:string) { 'a~b' }
97
+ let(:expected) { ['~', 'a', 'b']}
98
+ it { expect(query.send(:expression, string)).to eq expected }
99
+ end
100
+ context 'with a !~ sign' do
101
+ let(:string) { 'a!~b' }
102
+ let(:expected) { ['not', ['~', 'a', 'b']]}
103
+ it { expect(query.send(:expression, string)).to eq expected }
104
+ end
37
105
  end
38
106
 
39
107
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hieracles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mose
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-11 00:00:00.000000000 Z
11
+ date: 2015-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty