beaker-hostgenerator 0.9.0 → 0.10.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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODVjZTk2ZjQxN2JkMDlkYTMyNDQ3OTU2YTNkNTcyMjQ3MzYyNGQ4Nw==
4
+ OGJmOWNmNjhmMDYwZTBmNjJlMzgxYzk1MjgwNDZmZGVlNDFkZjcxMw==
5
5
  data.tar.gz: !binary |-
6
- MmYzZjJhNWEwYmViZTU2MjY3YmM3MDFjZDE1ODA4OGIwY2ZmMWQxNg==
6
+ MmY3ZGU0MzczN2EyODJlYzgyYzUzMzFmZDIyZmJmNTNiZmE3NjNkNA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YWM2ZjI2MGQ2ODI4MTc1YWY2OTNkZDYxN2E5ZjkwZmQ3NmZlMGUwNjk0Yzg1
10
- YWJjOTc4MWRkYmJiNzA3MGQyNDBmMDE3OGMyN2UzYWUwZWM3NTc5MGE2OWIx
11
- NzJhMmJmYzU4NjYwNmZjYjU0ZGI0ZWJkNWRhNmE1ZGEwODIzNjE=
9
+ NmUxMGVjZTdkODM3ZjM4MDVkMmFkMDlkMjM3Mjk4MTg2ZTY5MDc1NWIxMWI5
10
+ M2ViNGJiMGYwMGNhOTc0MjE1N2MwOWE1NzEwZTU0NGJkZTZmYTRmYmJiZGNk
11
+ MjhiNDZhYmJjOTk4ODcxODk0M2MyMmQ5NTE4ODQ5MjJlMTI5OTk=
12
12
  data.tar.gz: !binary |-
13
- NDIzMzJiZjE2ZDEyNTQxNDIyZDI5MGE4ZThhMGNhNDY2OTc3OWYwYTNkY2Qw
14
- ZDFjYzBkMDlkYTkxMWQwOWFjNWE4MWEwMTVlODk2NjIxYzY0MzI4ZmNjOWQ0
15
- YWUxYjVmY2NkZDFlZjU1YzNlYzkwZjI1NmQzMDQzZGU0ZGEyZWE=
13
+ OTIyNWM4OWFmZTY5N2U4OWI2ZWYzZGMyODY2MWIxOGY0NDMzYmExOGUyZDcy
14
+ NTI4M2Q3YmNkMjdkYzQyN2IwNDExMjNhZDIwN2U4M2Y0NjM0NWZmNjBhMDI4
15
+ NDVhZDk0OTA5MGI3MTk1OWIxN2FhZGI0NjQ0NjI2NDAzOGU2NDI=
@@ -4,7 +4,9 @@ All notable changes to this project will be documented in this file.
4
4
  This project makes a strong effort to adhere to [Semantic
5
5
  Versioning](http://semver.org).
6
6
 
7
- ## [Unreleased][unreleased]
7
+ ## [0.10.0] - 2017-7-7
8
+ - Add map data structure support to arbitrary settings, which previously only
9
+ supported lists and primitives. Maps and lists can be combined.
8
10
 
9
11
  ## [0.9.0] - 2017-6-7
10
12
  - Add list data structure support to arbitrary settings, which previously only
data/README.md CHANGED
@@ -13,6 +13,7 @@ host config files using a compact command line SUT specification.
13
13
  - [Single host with Arbitrary Roles](#single-host-with-arbitrary-roles)
14
14
  - [Two hosts with multiple hypervisors and arbitrary host settings](#two-hosts-with-multiple-hypervisors-and-arbitrary-host-settings)
15
15
  - [Two hosts with arbitrary host settings with arbitrary lists](#two-hosts-with-arbitrary-host-settings-with-arbitrary-lists)
16
+ - [Arbitrary nested hashes and arrays](#arbitrary-nested-hashes-and-arrays)
16
17
  - [Arbitrary global configuration settings](#arbitrary-global-configuration-settings)
17
18
  - [Custom hypervisor](#custom-hypervisor)
18
19
  - [URL-encoded input](#url-encoded-input)
@@ -161,7 +162,7 @@ CONFIG:
161
162
  ### Two hosts with arbitrary host settings with arbitrary lists
162
163
 
163
164
  ```
164
- $ beaker-hostgenerator centos6-64m{disks=\[16\]-redhat7-64a{disks=\[8\,16\]}
165
+ $ beaker-hostgenerator centos6-64m{disks=\[16\]}-redhat7-64a{disks=\[8\,16\]}
165
166
  ```
166
167
 
167
168
  Will generate
@@ -200,6 +201,41 @@ CONFIG:
200
201
  pooling_api: http://vmpooler.delivery.puppetlabs.net/
201
202
  ```
202
203
 
204
+ ### Arbitrary nested hashes and arrays
205
+
206
+ ```
207
+ $ beaker-hostgenerator --global-config {host_tags={lifetime=4h}\,list=[{listkey=listvalue}]\} redhat7-64m{hostlist=\[string\,{key=value}\,1234\]}
208
+ ```
209
+
210
+ Will generate
211
+
212
+ ```yaml
213
+ ---
214
+ HOSTS:
215
+ redhat7-64-1:
216
+ pe_dir:
217
+ pe_ver:
218
+ pe_upgrade_dir:
219
+ pe_upgrade_ver:
220
+ hypervisor: vmpooler
221
+ platform: el-7-x86_64
222
+ template: redhat-7-x86_64
223
+ hostlist:
224
+ - string
225
+ - key: value
226
+ - 1234
227
+ roles:
228
+ - agent
229
+ - master
230
+ CONFIG:
231
+ nfs_server: none
232
+ consoleport: 443
233
+ pooling_api: http://vmpooler.delivery.puppetlabs.net/
234
+ host_tags:
235
+ lifetime: 4h
236
+ list:
237
+ - listkey: listvalue
238
+ ```
203
239
 
204
240
  ### Arbitrary global configuration settings
205
241
 
@@ -74,6 +74,11 @@ module BeakerHostGenerator
74
74
  # Merge in global configuration settings after the hypervisor defaults
75
75
  if options[:global_config]
76
76
  decoded = prepare(options[:global_config])
77
+ # Support for strings without '{}' was introduced, so just double
78
+ # check here to ensure that we pass in values surrounded by '{}'.
79
+ if !decoded.start_with?('{')
80
+ decoded = "{#{decoded}}"
81
+ end
77
82
  global_config = settings_string_to_map(decoded)
78
83
  config['CONFIG'].deep_merge!(global_config)
79
84
  end
@@ -195,9 +195,10 @@ module BeakerHostGenerator
195
195
 
196
196
  # Transforms the arbitrary host settings map from a string representation
197
197
  # to a proper hash map data structure for merging into the host
198
- # configuration.
198
+ # configuration. Supports arbitrary nested hashes and arrays.
199
199
  #
200
200
  # The string is expected to be of the form "{key1=value1,key2=[v2,v3],...}".
201
+ # Nesting looks like "{key1={nested_key=nested_value},list=[[list1, list2]]}".
201
202
  # Whitespace is expected to be properly quoted as it will not be treated
202
203
  # any different than non-whitespace characters.
203
204
  #
@@ -206,38 +207,120 @@ module BeakerHostGenerator
206
207
  # @param host_settings [String] Non-nil user input string that defines host
207
208
  # specific settings.
208
209
  #
209
- # @returns [Hash{String=>String|Array}] The host_settings string as a map.
210
+ # @returns [Hash{String=>String|Array|Hash}] The host_settings string as a map.
210
211
  def settings_string_to_map(host_settings)
211
- # Strip it down to a list of pairs
212
- # Splitting on all commas except inside `[]`
213
- settings_pairs =
214
- host_settings.
215
- delete('{}').
216
- split(/,(?=[^\]]*(?:\[|$))/).
217
- map { |keyvalue| keyvalue.split('=') }
218
-
219
- # Validate they're actually pairs, and that all keys are non-empty
220
- settings_pairs.each do |pair|
221
- if pair.length != 2
222
- raise BeakerHostGenerator::Exceptions::InvalidNodeSpecError,
223
- "Malformed host settings: #{host_settings}"
212
+
213
+ stringscan = StringScanner.new(host_settings)
214
+ object = nil
215
+ object_depth = []
216
+ current_depth = 0
217
+
218
+ # This loop scans until the next delimiter character is found. When
219
+ # the next delimiter is recognized, there is enough context in the
220
+ # substring to determine a course of action to modify the primary
221
+ # object. The `object_depth` object tracks which current object is
222
+ # being modified, and pops it off the end of the array when that
223
+ # data structure is completed.
224
+ #
225
+ # This algorithm would also support a base array, but since there
226
+ # is no need for that functionality, we just assume the string is
227
+ # always a representation of a hash.
228
+ loop do
229
+ blob = stringscan.scan_until(/\[|{|}|\]|,/)
230
+
231
+ break if blob.nil?
232
+
233
+ if stringscan.pos() == 1
234
+ object = {}
235
+ object_depth.push(object)
236
+ next
224
237
  end
225
- if pair.first.nil? || pair.first.empty?
226
- raise BeakerHostGenerator::Exceptions::InvalidNodeSpecError,
227
- "Malformed host settings: #{host_settings}"
238
+
239
+ current_type = object_depth[current_depth].class
240
+ current_object = object_depth[current_depth]
241
+
242
+ if blob == '['
243
+ current_object.push([])
244
+ object_depth.push(current_object.last)
245
+ current_depth = current_depth.next
246
+ next
228
247
  end
229
- end
230
248
 
231
- # Replace the remaining `,` to make array for arbitrary list if brackets exist
232
- settings_pairs.each do |pair|
233
- if pair[1].include?("[")
234
- pair[1] = pair[1].
235
- delete('[]').
236
- split(',')
249
+ if blob.start_with?('{')
250
+ current_object.push({})
251
+ object_depth.push(current_object.last)
252
+ current_depth = current_depth.next
253
+ next
254
+ end
255
+
256
+
257
+
258
+ if blob == ']' or blob == '}'
259
+ object_depth.pop
260
+ current_depth = current_depth.pred
261
+ next
262
+ end
263
+
264
+ # When there is assignment happening, we need to create a new
265
+ # corresponding data structure, add it to the object depth, and
266
+ # then change the current depth
267
+ if blob[-2] == '='
268
+ raise Beaker::HostGenerator::Exceptions::InvalidNodeSpecError unless blob.end_with?('{','[')
269
+ if blob[-1] == '{'
270
+ current_object[blob[0..-3]] = {}
271
+ else
272
+ current_object[blob[0..-3]] = []
273
+ end
274
+ object_depth.push(current_object[blob[0..-3]])
275
+ current_depth = current_depth.next
276
+ next
277
+ end
278
+
279
+ if blob[-1] == '}'
280
+ raise Beaker::HostGenerator::Exceptions::InvalidNodeSpecError if blob.count('=') != 1
281
+ key_pair = blob[0..-2].split('=')
282
+ raise Beaker::HostGenerator::Exceptions::InvalidNodeSpecError if key_pair.size != 2
283
+ key_pair.each do |element|
284
+ raise Beaker::HostGenerator::Exceptions::InvalidNodeSpecError if element.empty?
285
+ end
286
+ current_object[key_pair[0]] = key_pair[1]
287
+ object_depth.pop
288
+ current_depth = current_depth.pred
289
+ next
290
+ end
291
+
292
+ if blob == ','
293
+ next
294
+ end
295
+
296
+ if blob[-1] == ','
297
+ if current_type == Hash
298
+ key_pair = blob[0..-2].split('=')
299
+ raise Beaker::HostGenerator::Exceptions::InvalidNodeSpecError if key_pair.size != 2
300
+ key_pair.each do |element|
301
+ raise Beaker::HostGenerator::Exceptions::InvalidNodeSpecError if element.empty?
302
+ end
303
+ current_object[key_pair[0]] = key_pair[1]
304
+ next
305
+ elsif current_type == Array
306
+ current_object.push(blob[0..-2])
307
+ next
308
+ end
309
+ end
310
+
311
+ if blob[-1] == ']'
312
+ current_object.push(blob[0..-2])
313
+ object_depth.pop
314
+ current_depth = current_depth.pred
315
+ next
237
316
  end
238
317
  end
239
318
 
240
- Hash[settings_pairs]
319
+ object
320
+ rescue Exception => e
321
+ raise BeakerHostGenerator::Exceptions::InvalidNodeSpecError,
322
+ "Malformed host settings: #{host_settings}"
241
323
  end
324
+
242
325
  end
243
326
  end
@@ -1,5 +1,5 @@
1
1
  module BeakerHostGenerator
2
2
  module Version
3
- STRING = '0.9.0'
3
+ STRING = '0.10.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beaker-hostgenerator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Branan Purvine-Riley
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-06-07 00:00:00.000000000 Z
13
+ date: 2017-07-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: minitest
@@ -197,7 +197,6 @@ files:
197
197
  - Gemfile
198
198
  - HISTORY.md
199
199
  - LICENSE
200
- - MAINTAINERS
201
200
  - README.md
202
201
  - Rakefile
203
202
  - beaker-hostgenerator.gemspec
@@ -1,18 +0,0 @@
1
- {
2
- "version": 1,
3
- "file_format": "This MAINTAINERS file format is described at http://pup.pt/maintainers",
4
- "issues": "https://tickets.puppetlabs.com/browse/QENG",
5
- "internal_list": "https://groups.google.com/a/puppet.com/forum/?hl=en#!forum/discuss-quality-engineering",
6
- "people": [
7
- {
8
- "github": "nwolfe",
9
- "email": "nwolfe@puppet.com",
10
- "name": "Nate Wolfe"
11
- },
12
- {
13
- "github": "waynr",
14
- "email": "wayne@puppet.com",
15
- "name": "Wayne Warren"
16
- }
17
- ]
18
- }