nomad-stanza 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4f5d4e1b8c1d504911911177be69adaddf4bfb5ba541c04179779df10da08e9a
4
+ data.tar.gz: 0f0e9a4ccde6f615facfd58114228168de956b8abfb14f9027f23da9c4b6791f
5
+ SHA512:
6
+ metadata.gz: dbc1c8261341275b59edff2bfcc586ec8fe3b0078eddaa63d15f98f640652fb7a8f2881ae733e1b67d63f02c95ea2d25141c9f9f6fd0841c1c18ef4ba4c02393
7
+ data.tar.gz: dad99035feacb6079bb039e62b4434811fd3d0246675312e72a89df0bf01031ada7a3e8b0618c23f510ea0a0e8c203c76dae622ea47c04c502582c953f24a954
@@ -0,0 +1,7 @@
1
+ module Nomad
2
+ module Stanza; end
3
+ end
4
+
5
+ require 'nomad/stanza/definition'
6
+ require 'nomad/stanza/serializer'
7
+ require 'nomad/stanza/version'
@@ -0,0 +1,391 @@
1
+ require 'dry-struct'
2
+
3
+ module Nomad::Stanza
4
+ DURATION_REGEXP = /^(([\d]+\.)?[\d]+[smh])+$/.freeze
5
+
6
+ module Types
7
+ include Dry.Types()
8
+ end
9
+
10
+ class Base < Dry::Struct
11
+ transform_keys(&:to_sym)
12
+ end
13
+
14
+ class Artifact < Base
15
+ attributes(
16
+ source: Types::Strict::String,
17
+ destination: Types::Strict::String.meta(omittable: true),
18
+ mode: Types::Coercible::String.meta(omittable: true),
19
+ options: Types::Hash.map(Types::Coercible::String, Types::Coercible::String).meta(omittable: true),
20
+ )
21
+ end
22
+
23
+ class Affinity < Base
24
+ attributes(
25
+ attribute: Types::Strict::String.meta(omittable: true),
26
+ operator: Types::Strict::String.enum(
27
+ '=', '!=', '>', '>=', '<', '<=', 'regexp', 'set_contains_all', 'set_contains_any', 'version'
28
+ ).meta(omittable: true),
29
+ value: Types::Coercible::String.meta(omittable: true),
30
+ weight: Types::Strict::Integer.constrained(gteq: -100, lteq: 100).default(50),
31
+ )
32
+ end
33
+
34
+ class CheckRestart < Base
35
+ attributes(
36
+ limit: Types::Strict::Integer.constrained(gteq: 0).default(0),
37
+ grace: Types::Strict::String.constrained(format: DURATION_REGEXP).default('1s'.freeze),
38
+ ignore_warnings: Types::Strict::Bool.default(false),
39
+ )
40
+ end
41
+
42
+ class Check < Base
43
+ attributes(
44
+ name: Types::Strict::String.meta(omittable: true),
45
+ type: Types::Strict::String.enum('grpc', 'http', 'script', 'tcp'),
46
+ port: Types::Coercible::String.meta(omittable: true),
47
+ protocol: Types::Strict::String.enum('http', 'https').meta(omittable: true),
48
+ path: Types::Strict::String.meta(omittable: true),
49
+ interval: Types::Strict::String.constrained(format: DURATION_REGEXP),
50
+ timeout: Types::Strict::String.constrained(format: DURATION_REGEXP),
51
+ command: Types::Strict::String.meta(omittable: true),
52
+ args: Types.Array(Types::Strict::String).meta(omittable: true),
53
+ grpc_service: Types::Strict::String.meta(omittable: true),
54
+ grpc_use_tls: Types::Strict::Bool.meta(omittable: true),
55
+ tls_skip_verify: Types::Strict::Bool.meta(omittable: true),
56
+ method: Types::Strict::String.meta(omittable: true),
57
+ header: Types::Hash.map(Types::Coercible::String, Types.Array(Types::Coercible::String)).meta(omittable: true),
58
+ check_restart: Types.Constructor(CheckRestart).meta(omittable: true),
59
+ initial_status: Types::Strict::String.enum('passing', 'warning', 'critical').meta(omittable: true),
60
+ address_mode: Types::Strict::String.meta(omittable: true),
61
+ )
62
+ end
63
+
64
+ class Constraint < Base
65
+ attributes(
66
+ attribute: Types::Strict::String.meta(omittable: true),
67
+ operator: Types::Strict::String.enum(
68
+ '=', '!=', '>', '>=', '<', '<=',
69
+ 'distinct_hosts', 'distinct_property', 'regexp', 'set_contains', 'version', 'is_set', 'is_not_set'
70
+ ).meta(omittable: true),
71
+ value: Types::Coercible::String.meta(omittable: true),
72
+ )
73
+ end
74
+
75
+ class Device < Base
76
+ attributes(
77
+ id: Types::Strict::String,
78
+ count: Types::Strict::Integer.constrained(gteq: 1).default(1),
79
+ constraint: Types.Array(Constraint).meta(omittable: true),
80
+ affinity: Types.Array(Affinity).meta(omittable: true),
81
+ )
82
+ end
83
+
84
+ class DispatchPayload < Base
85
+ attributes(
86
+ file: Types::Strict::String,
87
+ )
88
+ end
89
+
90
+ class EphemeralDisk < Base
91
+ attributes(
92
+ migrate: Types::Strict::Bool.default(false),
93
+ size: Types::Strict::Integer.constrained(gteq: 0).default(300),
94
+ sticky: Types::Strict::Bool.default(false),
95
+ )
96
+ end
97
+
98
+ class Logs < Base
99
+ attributes(
100
+ max_files: Types::Strict::Integer.constrained(gteq: 1).default(10),
101
+ max_file_size: Types::Strict::Integer.constrained(gteq: 1).default(10),
102
+ )
103
+ end
104
+
105
+ class Migrate < Base
106
+ attributes(
107
+ max_parallel: Types::Strict::Integer.constrained(gteq: 0).default(1),
108
+ health_check: Types::Strict::String.default('checks'.freeze).enum('checks', 'task_states'),
109
+ min_healthy_time: Types::Strict::String.constrained(format: DURATION_REGEXP).default('10s'.freeze),
110
+ healthy_deadline: Types::Strict::String.constrained(format: DURATION_REGEXP).default('5m'.freeze),
111
+ )
112
+ end
113
+
114
+ class NetworkPort < Base
115
+ attributes(
116
+ id: Types::Strict::String,
117
+ static: Types::Strict::Integer.constrained(gteq: 0, lteq: 65535).meta(omittable: true),
118
+ )
119
+ end
120
+
121
+ class Network < Base
122
+ attributes(
123
+ mbits: Types::Strict::Integer.constrained(gteq: 1).default(10),
124
+ port: Types.Array(NetworkPort).meta(omittable: true),
125
+ )
126
+ end
127
+
128
+ class Parameterized < Base
129
+ attributes(
130
+ payload: Types::Strict::String.default('optional'.freeze).enum('optional', 'required', 'forbidden'),
131
+ meta_required: Types.Array(Types::Strict::String).meta(omittable: true),
132
+ meta_optional: Types.Array(Types::Strict::String).meta(omittable: true),
133
+ )
134
+ end
135
+
136
+ class Periodic < Base
137
+ attributes(
138
+ cron: Types::Strict::String,
139
+ prohibit_overlap: Types::Strict::Bool.default(false),
140
+ time_zone: Types::Strict::String.default('UTC'.freeze),
141
+ )
142
+ end
143
+
144
+ class Reschedule < Base
145
+ attributes(
146
+ attempts: Types::Strict::Integer.constrained(gteq: 0).meta(omittable: true),
147
+ interval: Types::Strict::String.constrained(format: DURATION_REGEXP).meta(omittable: true),
148
+ delay: Types::Strict::String.constrained(format: DURATION_REGEXP),
149
+ delay_function: Types::Strict::String.enum('constant', 'exponential', 'fibonacci'),
150
+ max_delay: Types::Strict::String.constrained(format: DURATION_REGEXP).meta(omittable: true),
151
+ unlimited: Types::Strict::Bool,
152
+ )
153
+ end
154
+
155
+ class Resources < Base
156
+ attributes(
157
+ cpu: Types::Strict::Integer.constrained(gteq: 1).default(100),
158
+ memory: Types::Strict::Integer.constrained(gteq: 1).default(300),
159
+ network: Types.Constructor(Network).meta(omittable: true),
160
+ device: Types.Array(Device).meta(omittable: true),
161
+ )
162
+ end
163
+
164
+ class Restart < Base
165
+ attributes(
166
+ attempts: Types::Strict::Integer.constrained(gteq: 0).meta(omittable: true),
167
+ delay: Types::Strict::String.constrained(format: DURATION_REGEXP).default('15s'.freeze),
168
+ interval: Types::Strict::String.constrained(format: DURATION_REGEXP).meta(omittable: true),
169
+ mode: Types::Strict::String.default('fail'.freeze).enum('delay', 'fail'),
170
+ )
171
+ end
172
+
173
+ class Service < Base
174
+ attributes(
175
+ name: Types::Strict::String.meta(omittable: true),
176
+ port: Types::Coercible::String.meta(omittable: true),
177
+ tags: Types.Array(Types::Strict::String).meta(omittable: true),
178
+ canary_tags: Types.Array(Types::Strict::String).meta(omittable: true),
179
+ address_mode: Types::Strict::String.enum('auto', 'driver', 'host').meta(omittable: true),
180
+ check: Types.Array(Check).meta(omittable: true),
181
+ )
182
+ end
183
+
184
+ class SpreadTarget < Base
185
+ attributes(
186
+ id: Types::Strict::String,
187
+ value: Types::Strict::String.meta(omittable: true),
188
+ percent: Types::Strict::Integer.constrained(gteq: 0, lteq: 100),
189
+ )
190
+ end
191
+
192
+ class Spread < Base
193
+ attributes(
194
+ attribute: Types::Strict::String,
195
+ weight: Types::Strict::Integer.constrained(gteq: 0, lteq: 100),
196
+ target: Types.Array(SpreadTarget).meta(omittable: true),
197
+ )
198
+ end
199
+
200
+ class Template < Base
201
+ attributes(
202
+ data: Types::Strict::String.meta(omittable: true),
203
+ source: Types::Strict::String.meta(omittable: true),
204
+ destination: Types::Strict::String,
205
+ perms: Types::Strict::String.constrained(format: /^[0-7]{3}$/).default('644'.freeze),
206
+ change_mode: Types::Strict::String.default('restart'.freeze).enum('noop', 'restart', 'signal'),
207
+ change_signal: Types::Strict::String.meta(omittable: true),
208
+ splay: Types::Strict::String.constrained(format: DURATION_REGEXP).default('5s'.freeze),
209
+ left_delimiter: Types::Strict::String.meta(omittable: true),
210
+ right_delimiter: Types::Strict::String.meta(omittable: true),
211
+ env: Types::Strict::Bool.meta(omittable: true),
212
+ vault_grace: Types::Strict::String.constrained(format: DURATION_REGEXP).meta(omittable: true),
213
+ )
214
+ end
215
+
216
+ class Update < Base
217
+ attributes(
218
+ max_parallel: Types::Strict::Integer.constrained(gteq: 0).default(0),
219
+ health_check: Types::Strict::String.default('checks'.freeze).enum('checks', 'task_states', 'manual'),
220
+ min_healthy_time: Types::Strict::String.constrained(format: DURATION_REGEXP).default('10s'.freeze),
221
+ healthy_deadline: Types::Strict::String.constrained(format: DURATION_REGEXP).default('5m'.freeze),
222
+ progress_deadline: Types::Strict::String.constrained(format: DURATION_REGEXP).default('10m'.freeze),
223
+ auto_revert: Types::Strict::Bool.default(false),
224
+ auto_promote: Types::Strict::Bool.default(false),
225
+ canary: Types::Strict::Integer.constrained(gteq: 0).default(0),
226
+ stagger: Types::Strict::String.constrained(format: DURATION_REGEXP).default('30s'.freeze),
227
+ )
228
+ end
229
+
230
+ class Vault < Base
231
+ attributes(
232
+ policies: Types.Array(Types::Strict::String),
233
+ change_mode: Types::Strict::String.default('restart'.freeze).enum('noop', 'restart', 'signal'),
234
+ change_signal: Types::Strict::String.meta(omittable: true),
235
+ env: Types::Strict::Bool.default(true),
236
+ )
237
+ end
238
+
239
+ class DockerMount < Base
240
+ attributes(
241
+ type: Types::Strict::String.meta(omittable: true),
242
+ source: Types::Strict::String.meta(omittable: true),
243
+ target: Types::Strict::String,
244
+ readonly: Types::Strict::Bool.meta(omittable: true),
245
+ volume_options: Types::Hash.map(Types::Coercible::String, Types::Any).meta(omittable: true),
246
+ bind_options: Types::Hash.map(Types::Coercible::String, Types::Any).meta(omittable: true),
247
+ tmpfs_options: Types::Hash.map(Types::Coercible::String, Types::Any).meta(omittable: true),
248
+ )
249
+ end
250
+
251
+ class DockerDevice < Base
252
+ attributes(
253
+ host_path: Types::Strict::String,
254
+ container_path: Types::Strict::String,
255
+ cgroup_permissions: Types::Strict::String.meta(omittable: true),
256
+ )
257
+ end
258
+
259
+ class DockerConfigAuth < Base
260
+ attributes(
261
+ username: Types::Strict::String.meta(omittable: true),
262
+ password: Types::Strict::String.meta(omittable: true),
263
+ email: Types::Strict::String.meta(omittable: true),
264
+ server_address: Types::Strict::String.meta(omittable: true),
265
+ )
266
+ end
267
+
268
+ class DockerConfigLogging < Base
269
+ attributes(
270
+ type: Types::Strict::String.meta(omittable: true),
271
+ config: Types::Hash.map(Types::Coercible::String, Types::Coercible::String).meta(omittable: true),
272
+ )
273
+ end
274
+
275
+ class DockerConfig < Base
276
+ attributes(
277
+ image: Types::Strict::String,
278
+ force_pull: Types::Strict::Bool.meta(omittable: true),
279
+ entrypoint: Types::Strict::String.meta(omittable: true),
280
+ command: Types::Strict::String.meta(omittable: true),
281
+ args: Types.Array(Types::Strict::String).meta(omittable: true),
282
+ work_dir: Types::Strict::String.meta(omittable: true),
283
+ volume_driver: Types::Strict::String.meta(omittable: true),
284
+ volumes: Types.Array(Types::Strict::String).meta(omittable: true),
285
+ mounts: Types.Array(DockerMount).meta(omittable: true),
286
+ devices: Types.Array(DockerDevice).meta(omittable: true),
287
+ port_map: Types::Hash.map(Types::Coercible::String, Types::Coercible::Integer).meta(omittable: true),
288
+ network_aliases: Types.Array(Types::Strict::String).meta(omittable: true),
289
+ network_mode: Types::Strict::String.meta(omittable: true),
290
+ mac_address: Types::Strict::String.meta(omittable: true),
291
+ ipv4_address: Types::Strict::String.meta(omittable: true),
292
+ ipv6_address: Types::Strict::String.meta(omittable: true),
293
+ advertise_ipv6_address: Types::Strict::Bool.meta(omittable: true),
294
+ sysctl: Types::Hash.map(Types::Coercible::String, Types::Coercible::String).meta(omittable: true),
295
+ ulimit: Types::Hash.map(Types::Coercible::String, Types::Coercible::String).meta(omittable: true),
296
+ privileged: Types::Strict::Bool.meta(omittable: true),
297
+
298
+ auth: Types.Constructor(DockerConfigAuth).meta(omittable: true),
299
+ auth_soft_fail: Types::Strict::Bool.meta(omittable: true),
300
+ cap_add: Types.Array(Types::Strict::String).meta(omittable: true),
301
+ cap_drop: Types.Array(Types::Strict::String).meta(omittable: true),
302
+ cpu_cfs_period: Types::Strict::Integer.constrained(gteq: 1).meta(omittable: true),
303
+ cpu_hard_limit: Types::Strict::Bool.meta(omittable: true),
304
+ dns_options: Types.Array(Types::Strict::String).meta(omittable: true),
305
+ dns_search_domains: Types.Array(Types::Strict::String).meta(omittable: true),
306
+ dns_servers: Types.Array(Types::Strict::String).meta(omittable: true),
307
+ extra_hosts: Types.Array(Types::Strict::String).meta(omittable: true),
308
+ hostname: Types::Strict::String.meta(omittable: true),
309
+ interactive: Types::Strict::Bool.meta(omittable: true),
310
+ ipc_mode: Types::Strict::String.meta(omittable: true),
311
+ labels: Types::Hash.map(Types::Coercible::String, Types::Coercible::String).meta(omittable: true),
312
+ load: Types::Strict::String.meta(omittable: true),
313
+ logging: Types.Constructor(DockerConfigLogging).meta(omittable: true),
314
+ pid_mode: Types::Strict::String.meta(omittable: true),
315
+ pids_limit: Types::Strict::Integer.constrained(gteq: 1).meta(omittable: true),
316
+ readonly_rootfs: Types::Strict::Bool.meta(omittable: true),
317
+ security_opt: Types.Array(Types::Strict::String).meta(omittable: true),
318
+ shm_size: Types::Strict::Integer.constrained(gteq: 1).meta(omittable: true),
319
+ storage_opt: Types::Hash.map(Types::Coercible::String, Types::Coercible::String).meta(omittable: true),
320
+ tty: Types::Strict::Bool.meta(omittable: true),
321
+ userns_mode: Types::Strict::String.meta(omittable: true),
322
+ uts_mode: Types::Strict::String.meta(omittable: true),
323
+ )
324
+ end
325
+
326
+ class Task < Base
327
+ attributes(
328
+ id: Types::Strict::String,
329
+ leader: Types::Strict::Bool.meta(omittable: true),
330
+ kill_timeout: Types::Strict::String.constrained(format: DURATION_REGEXP).default('5s'.freeze),
331
+ kill_signal: Types::Strict::String.meta(omittable: true),
332
+ shutdown_delay: Types::Strict::String.constrained(format: DURATION_REGEXP).default('0s'.freeze),
333
+ constraint: Types.Array(Constraint).meta(omittable: true),
334
+ affinity: Types.Array(Affinity).meta(omittable: true),
335
+ driver: Types::Strict::String,
336
+ user: Types::Strict::String.meta(omittable: true),
337
+ config: Types.Constructor(DockerConfig).meta(omittable: true),
338
+ env: Types::Hash.map(Types::Coercible::String, Types::Coercible::String).meta(omittable: true),
339
+ dispatch_payload: Types.Constructor(DispatchPayload).meta(omittable: true),
340
+ artifact: Types.Array(Artifact).meta(omittable: true),
341
+ template: Types.Array(Template).meta(omittable: true),
342
+ resources: Types.Constructor(Resources),
343
+ service: Types.Array(Service).meta(omittable: true),
344
+ logs: Types.Constructor(Logs).meta(omittable: true),
345
+ meta: Types::Hash.map(Types::Coercible::String, Types::Coercible::String).meta(omittable: true),
346
+ vault: Types.Constructor(Vault).meta(omittable: true),
347
+ )
348
+ end
349
+
350
+ class Group < Base
351
+ attributes(
352
+ id: Types::Strict::String,
353
+ count: Types::Strict::Integer.constrained(gteq: 1).default(1),
354
+ constraint: Types.Array(Constraint).meta(omittable: true),
355
+ affinity: Types.Array(Affinity).meta(omittable: true),
356
+ spread: Types.Array(Spread).meta(omittable: true),
357
+ update: Types.Constructor(Update).meta(omittable: true),
358
+ migrate: Types.Constructor(Migrate).meta(omittable: true),
359
+ reschedule: Types.Constructor(Reschedule).meta(omittable: true),
360
+ restart: Types.Constructor(Restart).meta(omittable: true),
361
+ ephemeral_disk: Types.Constructor(EphemeralDisk).meta(omittable: true),
362
+ task: Types.Array(Task),
363
+ meta: Types::Hash.map(Types::Coercible::String, Types::Coercible::String).meta(omittable: true),
364
+ vault: Types.Constructor(Vault).meta(omittable: true),
365
+ )
366
+ end
367
+
368
+ class Job < Base
369
+ attributes(
370
+ id: Types::Strict::String,
371
+ type: Types::Strict::String.default('service'.freeze).enum('service', 'system', 'batch'),
372
+ region: Types::Strict::String.default('global'.freeze),
373
+ datacenters: Types.Array(Types::Strict::String),
374
+ namespace: Types::Strict::String.meta(omittable: true),
375
+ priority: Types::Strict::Integer.constrained(gteq: 1, lteq: 100).default(50),
376
+ all_at_once: Types::Strict::Bool.meta(omittable: true),
377
+ constraint: Types.Array(Constraint).meta(omittable: true),
378
+ affinity: Types.Array(Affinity).meta(omittable: true),
379
+ spread: Types.Array(Spread).meta(omittable: true),
380
+ update: Types.Constructor(Update).meta(omittable: true),
381
+ migrate: Types.Constructor(Migrate).meta(omittable: true),
382
+ reschedule: Types.Constructor(Reschedule).meta(omittable: true),
383
+ parameterized: Types.Constructor(Parameterized).meta(omittable: true),
384
+ periodic: Types.Constructor(Periodic).meta(omittable: true),
385
+ group: Types.Array(Group),
386
+ meta: Types::Hash.map(Types::Coercible::String, Types::Coercible::String).meta(omittable: true),
387
+ vault: Types.Constructor(Vault).meta(omittable: true),
388
+ vault_token: Types::Strict::String.meta(omittable: true),
389
+ )
390
+ end
391
+ end
@@ -0,0 +1,48 @@
1
+ require 'hydrochlorb'
2
+
3
+ class Nomad::Stanza::Serializer
4
+ class << self
5
+ def serialize(obj, indent: 2)
6
+ raise ArgumentError, 'Nomad::Stanza::Job is required.' unless obj.is_a? Nomad::Stanza::Job
7
+
8
+ builder = Hydrochlorb.build do
9
+ instance_eval &build_proc(obj, 'job', obj.id)
10
+ end.to_hcl(indent: indent)
11
+ end
12
+
13
+ def build_proc(obj, key, id = nil)
14
+ proc do
15
+ add *[key, id].compact do
16
+ obj.class.schema.each do |key|
17
+ k = key.name
18
+ v = obj.attributes[k]
19
+ if k == :id or v.nil?
20
+ next
21
+ elsif v.is_a? Nomad::Stanza::Base
22
+ if v.class.has_attribute?(:id)
23
+ instance_eval &build_proc(v, k, v.id)
24
+ else
25
+ instance_eval &build_proc(v, k)
26
+ end
27
+ elsif v.is_a? Array
28
+ member = obj.class.schema.key(k).type.type.member
29
+ if member.is_a? Class and member.ancestors.include? Nomad::Stanza::Base
30
+ v.each do |i|
31
+ if i.class.has_attribute?(:id)
32
+ instance_eval &build_proc(i, k, i.id)
33
+ else
34
+ instance_eval &build_proc(i, k)
35
+ end
36
+ end
37
+ else
38
+ add k, v
39
+ end
40
+ else
41
+ add k, v
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,10 @@
1
+ module Nomad
2
+ module Stanza
3
+ VERSION = '0.0.1'.freeze
4
+
5
+ def version
6
+ VERSION
7
+ end
8
+ module_function :version
9
+ end
10
+ end
@@ -0,0 +1 @@
1
+ require 'nomad/stanza'
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nomad-stanza
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Rianol Jou
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-08-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dry-struct
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: hydrochlorb
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '12.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '12.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.8'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.8'
83
+ description:
84
+ email:
85
+ - rianol.jou@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - lib/nomad/stanza.rb
91
+ - lib/nomad/stanza/definition.rb
92
+ - lib/nomad/stanza/serializer.rb
93
+ - lib/nomad/stanza/version.rb
94
+ - spec/spec_helper.rb
95
+ homepage: https://github.com/RiANOl/nomad-stanza
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '2.3'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubygems_version: 3.0.3
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Provide Nomad stanzas definition and serializer.
118
+ test_files:
119
+ - spec/spec_helper.rb