wash 0.1.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.
- checksums.yaml +7 -0
- data/lib/wash/entry.rb +345 -0
- data/lib/wash/method.rb +52 -0
- data/lib/wash/streamer.rb +24 -0
- data/lib/wash.rb +141 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f0c229c4c749d26525382c4c26255044308b763335b4d2d6d2ea8aa3495fb9b9
|
4
|
+
data.tar.gz: f60ba8213ec625de9ee9961db8bccc92c85af8a30fd916056d69809446fb1987
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 95ffb1adfde494f374e7dc76d02b68074ed120505e224da3667a80f9f15cc188b72fa158094a0f6dd755116a6964b396c8a65b0c67888ca4bc50603cd9f9f629
|
7
|
+
data.tar.gz: 6cd43ebb0dd830c14e8bf079e33dedd65fc2c25ccb6488b00073e5cf783f9b178f52992a04ae3773ed873fb5743a31774a9a2c1e642f6ae2a95190d53749ff96
|
data/lib/wash/entry.rb
ADDED
@@ -0,0 +1,345 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wash
|
4
|
+
# Entry represents a common base class for Wash entries. All plugin entries
|
5
|
+
# should extend this class.
|
6
|
+
class Entry
|
7
|
+
class << self
|
8
|
+
# attributes is a class-level tag specifying all the attributes that
|
9
|
+
# make sense for instances of this specific kind of entry. It will
|
10
|
+
# pass the specified attributes along to attr_accessor so that instances
|
11
|
+
# can set their values. For example, something like
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# class Foo
|
15
|
+
# # Instances of Foo will be able to set the @mtime and @meta fields
|
16
|
+
# attributes :mtime, :meta
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# @param [Symbol] attr An attribute that will be set
|
20
|
+
# @param [Symbol] attrs More attributes that will be set
|
21
|
+
def attributes(attr, *attrs)
|
22
|
+
@attributes ||= []
|
23
|
+
@attributes += set_fields(attr, *attrs)
|
24
|
+
end
|
25
|
+
|
26
|
+
# slash_replacer is a class-level tag that specifies the slash replacer.
|
27
|
+
# It should only be used if there is a chance that instances of the given
|
28
|
+
# class can contain a "#" in their names. Otherwise, slash_replacer should
|
29
|
+
# be ignored.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# class Foo
|
33
|
+
# # Tell Wash to replace all "/"es with ":" in the given Foo instance's
|
34
|
+
# # name
|
35
|
+
# slash_replacer ":"
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# @param [String] char The slash replacer
|
39
|
+
def slash_replacer(char)
|
40
|
+
@slash_replacer = char
|
41
|
+
end
|
42
|
+
|
43
|
+
# state is a class-level tag that specifies the minimum state required
|
44
|
+
# to reconstruct all instances of this specific kind of entry. Each specified
|
45
|
+
# state field will be passed along to attr_accessor so that instances can
|
46
|
+
# get/set their values.
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# class Foo
|
50
|
+
# # Indicates that api_key is the minimum state required to reconstruct
|
51
|
+
# # instances of Foo. The gem will serialize the api_key as part of each
|
52
|
+
# # instance's state key when passing them along to Wash. If Wash invokes
|
53
|
+
# # a method on a specific instance, then Wash.run will restore the api_key
|
54
|
+
# # prior to invoking the method (so all methods are free to directly reference
|
55
|
+
# # the @api_key field). Thus, plugin authors do not have to manage their entries'
|
56
|
+
# # states; the gem will do it for them via the state tag.
|
57
|
+
# state :api_key
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# Note that Wash.run uses {Class#allocate} when it reconstructs the entries, so
|
61
|
+
# it does not call the initialize method.
|
62
|
+
def state(field, *fields)
|
63
|
+
@state ||= []
|
64
|
+
@state += set_fields(field, *fields)
|
65
|
+
end
|
66
|
+
|
67
|
+
# label is a class-level tag specifying the entry's label. It is a helper for
|
68
|
+
# Entry schemas.
|
69
|
+
#
|
70
|
+
# @param lbl The label.
|
71
|
+
def label(lbl)
|
72
|
+
@label = lbl
|
73
|
+
end
|
74
|
+
|
75
|
+
# is_singleton is a class-level tag indicating that the given Entry's a singleton.
|
76
|
+
# It is a helper for Entry schemas.
|
77
|
+
#
|
78
|
+
# Note that if an Entry has the is_singleton tag and its name is not filled-in
|
79
|
+
# when that Entry is listed, then the Entry's name will be set to the specified
|
80
|
+
# label. This means that plugin authors do not have to set singleton entries'
|
81
|
+
# names, and it also enforces the convention that singleton entries' labels should
|
82
|
+
# match their names.
|
83
|
+
#
|
84
|
+
# @example
|
85
|
+
# class Foo
|
86
|
+
# label 'foo'
|
87
|
+
# # If Foo's instance does not set @name, then the gem will set @name to 'foo'
|
88
|
+
# is_singleton
|
89
|
+
# end
|
90
|
+
def is_singleton
|
91
|
+
@singleton = true
|
92
|
+
end
|
93
|
+
|
94
|
+
# meta_attribute_schema sets the meta attribute's schema to schema. It is a helper
|
95
|
+
# for Entry schemas.
|
96
|
+
#
|
97
|
+
# @param schema A hash containing the meta attribute's JSON schema
|
98
|
+
def meta_attribute_schema(schema)
|
99
|
+
@meta_attribute_schema = schema
|
100
|
+
end
|
101
|
+
|
102
|
+
# metadata_schema sets the metadata schema to schema. It is a helper for Entry schemas.
|
103
|
+
#
|
104
|
+
# @param schema A hash containing the metadata's JSON schema
|
105
|
+
def metadata_schema(schema)
|
106
|
+
@metadata_schema = schema
|
107
|
+
end
|
108
|
+
|
109
|
+
# parent_of indicates that this kind of Entry is the parent of the given child classes
|
110
|
+
# (i.e. child entries). It is a helper for Entry schemas.
|
111
|
+
#
|
112
|
+
# @example
|
113
|
+
# class Foo
|
114
|
+
# # This indicates that Foo#list will return instances of Bar and Baz. Note
|
115
|
+
# # that both direct class constants (Bar) and strings ('Baz') are valid
|
116
|
+
# # input. The latter's useful when the child class is loaded after the
|
117
|
+
# # parent.
|
118
|
+
# parent_of Bar, 'Baz'
|
119
|
+
# end
|
120
|
+
#
|
121
|
+
# @param [Wash::Entry] child_klass A child class object.
|
122
|
+
# @param [Wash::Entry] child_klasses More child class objects.
|
123
|
+
def parent_of(child_klass, *child_klasses)
|
124
|
+
@child_klasses ||= []
|
125
|
+
@child_klasses += [child_klass] + child_klasses
|
126
|
+
end
|
127
|
+
|
128
|
+
# children returns this Entry's child classes. It is a helper for Entry schemas, and
|
129
|
+
# is useful for DRY'ing up schema code when one kind of Entry's children matches another
|
130
|
+
# kind of Entry's children.
|
131
|
+
#
|
132
|
+
# @example
|
133
|
+
# class VolumeDir
|
134
|
+
# parent_of 'VolumeDir', 'VolumeFile'
|
135
|
+
# end
|
136
|
+
#
|
137
|
+
# class Volume
|
138
|
+
# parent_of *VolumeDir.children
|
139
|
+
# end
|
140
|
+
def children
|
141
|
+
@child_klasses
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def schema(visited)
|
147
|
+
visited[type_id] = {
|
148
|
+
label: @label,
|
149
|
+
methods: methods,
|
150
|
+
singleton: @singleton,
|
151
|
+
meta_attribute_schema: @meta_attribute_schema,
|
152
|
+
metadata_schema: @metadata_schema,
|
153
|
+
}
|
154
|
+
unless @child_klasses
|
155
|
+
return
|
156
|
+
end
|
157
|
+
visited[type_id][:children] = @child_klasses
|
158
|
+
@child_klasses.each do |child_klass|
|
159
|
+
child_klass = const_get(child_klass)
|
160
|
+
if visited[child_klass.send(:type_id)]
|
161
|
+
next
|
162
|
+
end
|
163
|
+
child_klass.send(:schema, visited)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def methods
|
168
|
+
wash_methods = Method.instance_variable_get(:@methods)
|
169
|
+
methods = []
|
170
|
+
self.public_instance_methods.each do |method|
|
171
|
+
if wash_methods[method]
|
172
|
+
# Only include the Wash methods. This makes the script's output easier
|
173
|
+
# to read when debugging.
|
174
|
+
methods.push(method)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
unless Wash.send(:entry_schemas_enabled?)
|
178
|
+
# Don't include :schema if entry-schema support is not enabled. Otherwise,
|
179
|
+
# Wash will return an error since entry schemas are an "on/off" feature.
|
180
|
+
methods.delete(:schema)
|
181
|
+
end
|
182
|
+
methods
|
183
|
+
end
|
184
|
+
|
185
|
+
def type_id
|
186
|
+
self.name
|
187
|
+
end
|
188
|
+
|
189
|
+
def set_fields(field, *fields)
|
190
|
+
fields.unshift(field)
|
191
|
+
fields.each do |field|
|
192
|
+
attr_accessor field
|
193
|
+
end
|
194
|
+
fields
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# All entries have a name. Note that the name is always
|
199
|
+
# included in the entry's state hash.
|
200
|
+
attr_accessor :name
|
201
|
+
|
202
|
+
def to_json(*)
|
203
|
+
unless @name && @name.size > 0
|
204
|
+
unless singleton
|
205
|
+
raise "A nameless entry is being serialized. The entry is an instance of #{type_id}"
|
206
|
+
end
|
207
|
+
@name = label
|
208
|
+
end
|
209
|
+
|
210
|
+
hash = {
|
211
|
+
type_id: type_id,
|
212
|
+
name: @name,
|
213
|
+
}
|
214
|
+
|
215
|
+
# Include the methods
|
216
|
+
hash[:methods] = self.class.send(:methods).map do |method|
|
217
|
+
if prefetched_methods.include?(method)
|
218
|
+
[method, self.send(method)]
|
219
|
+
else
|
220
|
+
method
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Include the remaining keys. Note that these checks are here to
|
225
|
+
# ensure that we don't serialize empty keys. They're meant to save
|
226
|
+
# some space.
|
227
|
+
if attributes.size > 0 && (attributes_hash = to_hash(attributes))
|
228
|
+
hash[:attributes] = attributes_hash
|
229
|
+
end
|
230
|
+
if cache_ttls.size > 0
|
231
|
+
hash[:cache_ttls] = cache_ttls
|
232
|
+
end
|
233
|
+
if slash_replacer.size > 0
|
234
|
+
hash[:slash_replacer] = slash_replacer
|
235
|
+
end
|
236
|
+
hash[:state] = to_hash(state).merge(klass: type_id, name: @name).to_json
|
237
|
+
if Wash.send(:pretty_print?)
|
238
|
+
JSON.pretty_generate(hash)
|
239
|
+
else
|
240
|
+
JSON.generate(hash)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# type_id returns the entry's type ID, which is its fully-qualified class
|
245
|
+
# name.
|
246
|
+
def type_id
|
247
|
+
self.class.send(:type_id)
|
248
|
+
end
|
249
|
+
|
250
|
+
# prefetch indicates that the given methods should be prefetched. This means
|
251
|
+
# that the gem will invoke those methods on this particular entry instance and
|
252
|
+
# include their results when serializing that entry. Note that the methods are
|
253
|
+
# invoked during serialization.
|
254
|
+
#
|
255
|
+
# @example
|
256
|
+
# class Foo
|
257
|
+
# def initialize(content_size)
|
258
|
+
# if content_size < 10
|
259
|
+
# # content_size < 10, so tell the gem to invoke Foo#list and Foo#read
|
260
|
+
# # on this Foo instance during its serialization
|
261
|
+
# prefetch :list, :read
|
262
|
+
# end
|
263
|
+
# end
|
264
|
+
# end
|
265
|
+
#
|
266
|
+
# @param [Symbol] method A method that should be prefetched.
|
267
|
+
# @param [Symbol] methods More methods that should be prefetched.
|
268
|
+
def prefetch(method, *methods)
|
269
|
+
prefetched_methods.concat([method] + methods)
|
270
|
+
end
|
271
|
+
|
272
|
+
# cache_ttls sets the cache TTLs (time-to-live) of the given methods.
|
273
|
+
#
|
274
|
+
# @example
|
275
|
+
# class Foo
|
276
|
+
# def initialize(content_size)
|
277
|
+
# if content_size > 10000
|
278
|
+
# # content_size > 10000 so tell Wash to cache its read result for
|
279
|
+
# # 100 seconds
|
280
|
+
# cache_ttls read: 100
|
281
|
+
# end
|
282
|
+
# end
|
283
|
+
# end
|
284
|
+
#
|
285
|
+
# @param [Hash] ttls A hash of <method_name> => <method_ttl>
|
286
|
+
def cache_ttls(ttls = {})
|
287
|
+
@cache_ttls ||= {}
|
288
|
+
@cache_ttls = @cache_ttls.merge(ttls)
|
289
|
+
end
|
290
|
+
|
291
|
+
# schema returns the entry's schema. It should not be overridden.
|
292
|
+
def schema
|
293
|
+
schemaHash = {}
|
294
|
+
self.class.send(:schema, schemaHash)
|
295
|
+
schemaHash
|
296
|
+
end
|
297
|
+
|
298
|
+
private
|
299
|
+
|
300
|
+
def attributes
|
301
|
+
self.class.instance_variable_get(:@attributes) || []
|
302
|
+
end
|
303
|
+
|
304
|
+
def slash_replacer
|
305
|
+
self.class.instance_variable_get(:@slash_replacer) || ''
|
306
|
+
end
|
307
|
+
|
308
|
+
def state
|
309
|
+
self.class.instance_variable_get(:@state) || {}
|
310
|
+
end
|
311
|
+
|
312
|
+
def label
|
313
|
+
self.class.instance_variable_get(:@label)
|
314
|
+
end
|
315
|
+
|
316
|
+
def singleton
|
317
|
+
self.class.instance_variable_get(:@singleton)
|
318
|
+
end
|
319
|
+
|
320
|
+
def prefetched_methods
|
321
|
+
@prefetched_methods ||= []
|
322
|
+
end
|
323
|
+
|
324
|
+
def to_hash(fields)
|
325
|
+
field_hash = {}
|
326
|
+
fields.each do |field|
|
327
|
+
field = field.to_sym
|
328
|
+
if value = self.send(field)
|
329
|
+
field_hash[field] = self.send(field)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
field_hash
|
333
|
+
end
|
334
|
+
|
335
|
+
def restore_state(state)
|
336
|
+
state.each do |field, value|
|
337
|
+
accessor = "#{field}=".to_sym
|
338
|
+
unless self.respond_to?(accessor)
|
339
|
+
raise "#{field} is an invalid state value"
|
340
|
+
end
|
341
|
+
self.send(accessor, value)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
data/lib/wash/method.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wash
|
4
|
+
# @api private
|
5
|
+
module Method
|
6
|
+
def self.invoke(method, entry, *args)
|
7
|
+
method = method.to_sym
|
8
|
+
unless entry.respond_to?(method)
|
9
|
+
raise "Entry #{entry.name} (#{entry.type_id}) does not implement #{method}"
|
10
|
+
end
|
11
|
+
unless invocation = @methods[method]
|
12
|
+
raise "#{method} is not a supported Wash method"
|
13
|
+
end
|
14
|
+
invocation.call(entry, *args)
|
15
|
+
end
|
16
|
+
private_class_method :invoke
|
17
|
+
|
18
|
+
def self.method(name, &block)
|
19
|
+
name = name.to_sym
|
20
|
+
unless block
|
21
|
+
block = lambda do |entry, *args|
|
22
|
+
result = entry.send(name, *args)
|
23
|
+
Wash.send(:print_json, result)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
@methods ||= {}
|
27
|
+
@methods[name] = block
|
28
|
+
end
|
29
|
+
private_class_method :method
|
30
|
+
|
31
|
+
method(:list)
|
32
|
+
method(:read)
|
33
|
+
method(:metadata)
|
34
|
+
method(:schema)
|
35
|
+
|
36
|
+
method(:exec) do |entry, *args|
|
37
|
+
opts, cmd, args = Wash.send(:parse_json, args[0]), args[1], args[2..-1]
|
38
|
+
if opts[:stdin]
|
39
|
+
opts[:stdin] = STDIN
|
40
|
+
else
|
41
|
+
opts[:stdin] = nil
|
42
|
+
end
|
43
|
+
ec = entry.exec(cmd, args, opts)
|
44
|
+
exit ec
|
45
|
+
end
|
46
|
+
|
47
|
+
method(:stream) do |entry, _|
|
48
|
+
entry.stream
|
49
|
+
raise "stream should never return"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wash
|
4
|
+
# Streamer is a class meant to be used by implementations of Wash::Entry#stream.
|
5
|
+
class Streamer
|
6
|
+
def initialize
|
7
|
+
@first_chunk = true
|
8
|
+
end
|
9
|
+
|
10
|
+
# write writes the given chunk to STDOUT then flushes it to ensure that Wash
|
11
|
+
# receives the data. If the chunk is the first chunk that's written, then
|
12
|
+
# write will print the "200" header prior to writing the chunk.
|
13
|
+
#
|
14
|
+
# @param chunk The chunk to be written
|
15
|
+
def write(chunk)
|
16
|
+
if @first_chunk
|
17
|
+
puts("200")
|
18
|
+
@first_chunk = false
|
19
|
+
end
|
20
|
+
print(chunk)
|
21
|
+
STDOUT.flush
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/wash.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Wash
|
6
|
+
# pretty_print enables pretty printing of methods that produce
|
7
|
+
# JSON output. It is a useful debugging tool.
|
8
|
+
def self.pretty_print
|
9
|
+
@pretty_print = true
|
10
|
+
end
|
11
|
+
|
12
|
+
# enable_entry_schemas enables {Entry schema}[https://puppetlabs.github.io/wash/docs/#entry-schemas]
|
13
|
+
# support. See {Wash::Entry}'s documentation for more details on
|
14
|
+
# the available Entry schema helpers.
|
15
|
+
def self.enable_entry_schemas
|
16
|
+
@entry_schemas_enabled = true
|
17
|
+
end
|
18
|
+
|
19
|
+
# prefetch_entry_schemas enables schema-prefetching. This option
|
20
|
+
# should be enabled once external plugin development's finished.
|
21
|
+
# If the external plugin is not using Entry schemas, then this
|
22
|
+
# option can be ignored.
|
23
|
+
def self.prefetch_entry_schemas
|
24
|
+
@prefetch_entry_schemas = true
|
25
|
+
end
|
26
|
+
|
27
|
+
# on_sigterm will execute the provided block when the plugin script
|
28
|
+
# receives a SIGTERM/SIGINT signal. It is useful for handling
|
29
|
+
# plugin-specific cleanup like dangling processes, files, etc.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# class Foo
|
33
|
+
# # ...
|
34
|
+
# def stream
|
35
|
+
# # ...
|
36
|
+
# Wash.on_sigterm do
|
37
|
+
# # Kill any orphaned processes/files
|
38
|
+
# end
|
39
|
+
# # ...
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
def self.on_sigterm(&block)
|
43
|
+
sigterm_handlers << block
|
44
|
+
end
|
45
|
+
|
46
|
+
# run is the plugin script's run function. All plugin scripts using
|
47
|
+
# this gem should invoke this function once they've specified the
|
48
|
+
# desired configuration options (e.g. like pretty_print).
|
49
|
+
#
|
50
|
+
# @param [Wash::Entry] root_klass The plugin root's class object
|
51
|
+
#
|
52
|
+
# @param [Array<String>] argv The plugin script's arguments (usually ARGV).
|
53
|
+
def self.run(root_klass, argv)
|
54
|
+
Signal.trap('INT') do
|
55
|
+
handle_sigterm
|
56
|
+
exit 130
|
57
|
+
end
|
58
|
+
Signal.trap('TERM') do
|
59
|
+
handle_sigterm
|
60
|
+
exit 143
|
61
|
+
end
|
62
|
+
|
63
|
+
method, argv = next_arg(argv)
|
64
|
+
|
65
|
+
if method == "init"
|
66
|
+
config, argv = next_arg(argv)
|
67
|
+
root = root_klass.new
|
68
|
+
unless root.respond_to?(:init)
|
69
|
+
raise "Plugin root #{root.type_id} does not implement init."
|
70
|
+
end
|
71
|
+
config = parse_json(config)
|
72
|
+
root.init(config)
|
73
|
+
if @prefetch_entry_schemas
|
74
|
+
root.prefetch :schema
|
75
|
+
end
|
76
|
+
print_json(root)
|
77
|
+
return
|
78
|
+
end
|
79
|
+
|
80
|
+
_, argv = next_arg(argv)
|
81
|
+
|
82
|
+
state, argv = next_arg(argv)
|
83
|
+
state = parse_json(state)
|
84
|
+
klass = const_get(state.delete(:klass))
|
85
|
+
# Use klass#allocate instead of klass#new to give plugin authors
|
86
|
+
# more freedom in how they decide to setup their constructors
|
87
|
+
entry = klass.allocate
|
88
|
+
entry.send(:restore_state, state)
|
89
|
+
|
90
|
+
Method.send(:invoke, method, entry, *argv)
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.next_arg(argv)
|
94
|
+
if argv.size < 1
|
95
|
+
raise "Invalid plugin-script invocation. See https://puppetlabs.github.io/wash/docs/external_plugins/ for details on what this should look like"
|
96
|
+
end
|
97
|
+
return argv[0], argv[1..-1]
|
98
|
+
end
|
99
|
+
private_class_method :next_arg
|
100
|
+
|
101
|
+
def self.handle_sigterm
|
102
|
+
sigterm_handlers.each do |handler|
|
103
|
+
handler.call
|
104
|
+
end
|
105
|
+
end
|
106
|
+
private_class_method :handle_sigterm
|
107
|
+
|
108
|
+
def self.pretty_print?
|
109
|
+
@pretty_print
|
110
|
+
end
|
111
|
+
private_class_method :pretty_print?
|
112
|
+
|
113
|
+
def self.entry_schemas_enabled?
|
114
|
+
@entry_schemas_enabled
|
115
|
+
end
|
116
|
+
private_class_method :entry_schemas_enabled?
|
117
|
+
|
118
|
+
def self.print_json(result)
|
119
|
+
if pretty_print?
|
120
|
+
result_json = JSON.pretty_generate(result)
|
121
|
+
else
|
122
|
+
result_json = JSON.generate(result)
|
123
|
+
end
|
124
|
+
puts(result_json)
|
125
|
+
end
|
126
|
+
private_class_method :print_json
|
127
|
+
|
128
|
+
def self.parse_json(json)
|
129
|
+
JSON.parse(json,:symbolize_names => true)
|
130
|
+
end
|
131
|
+
private_class_method :parse_json
|
132
|
+
|
133
|
+
def self.sigterm_handlers
|
134
|
+
@sigterm_handlers ||= []
|
135
|
+
end
|
136
|
+
private_class_method :sigterm_handlers
|
137
|
+
|
138
|
+
require 'wash/entry'
|
139
|
+
require 'wash/method'
|
140
|
+
require 'wash/streamer'
|
141
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wash
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Puppet
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-07-23 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A library for building Wash external plugins
|
14
|
+
email:
|
15
|
+
- puppet@puppet.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/wash.rb
|
21
|
+
- lib/wash/entry.rb
|
22
|
+
- lib/wash/method.rb
|
23
|
+
- lib/wash/streamer.rb
|
24
|
+
homepage: https://github.com/puppetlabs/wash-ruby
|
25
|
+
licenses:
|
26
|
+
- Apache-2.0
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - "~>"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '2.3'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubygems_version: 3.0.3
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: A library for building Wash external plugins
|
47
|
+
test_files: []
|