beaker-pe 1.23.0 → 1.24.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
- MjlmYWQxODA1M2Q3NzI3ZTM0YWNkNzk0Y2E4MDI1YWJmMzVmNTc4ZA==
4
+ MDkyZjU4ZGQwODQwNWY4NGZlODZiMjRjY2NmOTlhOTNjMDc0ODM2Mg==
5
5
  data.tar.gz: !binary |-
6
- YWFiNmVkMTJiNDM1YTk1ODQ2MTk1ZDRlZWI3ZDJmYzM4MzQ3YjcxYg==
6
+ MDk4NzJiMGM3ZGYzYjdlZjlkZmFkZGM3MjY5ZjY1Y2VkOGE1MWY5MQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MTg4NTllZTMzNjBiMTZiZTM4YmUyYzQxNDllNDM4OTU4Yjg3ZDc0NzI0ODA0
10
- MTRjOTA3N2Y1ZDg2YWM1ZmU1NGRiYjY1ZDFmYjY2ZGVjZjZlYjMyMTRkNGEy
11
- MmZjNzkwNzcyYjIzYmI4ZjUxNjhmNGI1NmRjMjAxNmNkZGI2MTU=
9
+ NjhkMmEzMjE5NTZhMDgzZWM5NDA2MDA1ZTlmYzZjMGNlMzBmMmNjNTlkZjRj
10
+ ODE4YTEwYmViMDkwY2ZkM2FmMmNkNDQ3NTIzMGEyZmZkNWVhZDRhOWMxMDdl
11
+ NDRkMDRiMmIzNjE4NDNhNGVmMWMzODIwMTU5NGU2MmI5ZDZhZDQ=
12
12
  data.tar.gz: !binary |-
13
- YTJkOWVkYzc4ZjhhYWRkZmRlZWFkOTM2OTY1NmVjMjA1ZWRmYmUzODkzOWU2
14
- MThkYzYxOTJkMmM2MTc0NDk1NzE0ODhhMmNiNDkyNjVmN2EzZjZjNTJkMjFh
15
- ZmE0NzJiYmIwNWM4OTJkYzEwZGM0MmE1ZTE4ZTllOTc2N2Y0MTE=
13
+ MmRiMThhNWE3ZmJhNjExMDQ5NjEwNjhjNzAxOTg2ZWIwZTcxNGIwZTk0YjY4
14
+ ZWJkMGI0NTJlYzA5ZWI5NmNkYWQ0MzY1MDU3YmVmMzUxOTY3NjRkZWExMGYw
15
+ ODYxN2MyNWI5Y2E2ZTE4MzkzMDhlYjg5M2RiYjgyZDZjMTQwZWQ=
@@ -101,6 +101,30 @@ module Beaker
101
101
  end
102
102
  end
103
103
 
104
+ # Return agent nodes with 'lb_connect' role that are not loadbalancers
105
+ def loadbalancer_connecting_agents
106
+ lb_connect_nodes = select_hosts(roles: ['lb_connect'])
107
+ lb_connect_agents = lb_connect_nodes.reject { |h| h['roles'].include?('loadbalancer')}
108
+ end
109
+
110
+ # Returns true if loadbalncer exists and is configured with 'lb_connect' role
111
+ def lb_connect_loadbalancer_exists?
112
+ if (any_hosts_as?('loadbalancer'))
113
+ lb_node = select_hosts(roles: ['loadbalancer'])
114
+ lb_node.first['roles'].include?('lb_connect')
115
+ end
116
+ end
117
+
118
+ #Returns loadbalancer if host is an agent and loadbalancer has lb_connect role
119
+ #@param [Host] agent host with lb_connect role
120
+ def get_lb_downloadhost(host)
121
+ downloadhost = master
122
+ if( ! host['roles'].include?('loadbalancer') && lb_connect_loadbalancer_exists?)
123
+ downloadhost = loadbalancer
124
+ end
125
+ downloadhost
126
+ end
127
+
104
128
  # Generate the command line string needed to from a frictionless puppet-agent
105
129
  # install on this host in a PE environment.
106
130
  #
@@ -124,6 +148,14 @@ module Beaker
124
148
  end
125
149
  end
126
150
 
151
+ # If this is an agent node configured to connect to the loadbalancer
152
+ # using 'lb_connect' role, then use loadbalancer in the download url
153
+ # instead of master (PE-22051)
154
+ downloadhost = master
155
+ if( host['roles'].include?('lb_connect'))
156
+ downloadhost = get_lb_downloadhost(host)
157
+ end
158
+
127
159
  pe_debug = host[:pe_debug] || opts[:pe_debug] ? ' -x' : ''
128
160
  use_puppet_ca_cert = host[:use_puppet_ca_cert] || opts[:use_puppet_ca_cert]
129
161
 
@@ -135,7 +167,7 @@ module Beaker
135
167
  cert_validator = '[Net.ServicePointManager]::ServerCertificateValidationCallback = {\\$true}'
136
168
  end
137
169
 
138
- cmd = %Q{powershell -c "cd #{host['working_dir']};#{cert_validator};\\$webClient = New-Object System.Net.WebClient;\\$webClient.DownloadFile('https://#{master}:8140/packages/current/install.ps1', '#{host['working_dir']}/install.ps1');#{host['working_dir']}/install.ps1 -verbose #{frictionless_install_opts.join(' ')}"}
170
+ cmd = %Q{powershell -c "cd #{host['working_dir']};#{cert_validator};\\$webClient = New-Object System.Net.WebClient;\\$webClient.DownloadFile('https://#{downloadhost}:8140/packages/current/install.ps1', '#{host['working_dir']}/install.ps1');#{host['working_dir']}/install.ps1 -verbose #{frictionless_install_opts.join(' ')}"}
139
171
  else
140
172
  curl_opts = %w{--tlsv1 -O}
141
173
  if use_puppet_ca_cert
@@ -144,7 +176,7 @@ module Beaker
144
176
  curl_opts << '-k'
145
177
  end
146
178
 
147
- cmd = "FRICTIONLESS_TRACE='true'; export FRICTIONLESS_TRACE; cd #{host['working_dir']} && curl #{curl_opts.join(' ')} https://#{master}:8140/packages/current/install.bash && bash#{pe_debug} install.bash #{frictionless_install_opts.join(' ')}".strip
179
+ cmd = "FRICTIONLESS_TRACE='true'; export FRICTIONLESS_TRACE; cd #{host['working_dir']} && curl #{curl_opts.join(' ')} https://#{downloadhost}:8140/packages/current/install.bash && bash#{pe_debug} install.bash #{frictionless_install_opts.join(' ')}".strip
148
180
  end
149
181
 
150
182
  return cmd
@@ -376,33 +408,41 @@ module Beaker
376
408
  else
377
409
  _console_dispatcher = get_console_dispatcher_for_beaker_pe!
378
410
 
379
- # Check if we've already created a frictionless agent node group
380
- # to avoid errors creating the same node group when the beaker hosts file contains
381
- # multiple hosts with the same platform
382
- node_group = _console_dispatcher.get_node_group_by_name('Beaker Frictionless Agent')
383
- if node_group.nil? || node_group.empty?
384
- node_group = {}
385
- node_group['name'] = "Beaker Frictionless Agent"
386
- # Pin the master to the node
387
- node_group['rule'] = [ "and", [ '=', 'name', master.to_s ]]
388
- node_group['classes'] ||= {}
389
- end
411
+ # Add pe_repo packages to 'PE Master' group
412
+ # This change will alow us to test the standard workflow where we add pe_repo packages
413
+ # to PE Master group itself. This will also make it easy to download the packages to
414
+ # compilemasters(PE-22051)
415
+ # Previosuly, we were creating a new node group 'Beaker Frictionless Agent' and adding
416
+ # pe_repo packages to that group
417
+ #
418
+ node_group = _console_dispatcher.get_node_group_by_name('PE Master')
390
419
 
391
420
  # add the pe_repo platform class if it's not already present
392
- if ! node_group['classes'].include?(klass)
393
- node_group['classes'][klass] = {}
394
-
395
- _console_dispatcher.create_new_node_group_model(node_group)
396
- # The puppet agent run that will download the agent tarballs to the master can sometimes fail with
397
- # curl errors if there is a network hiccup. Use beakers `retry_on` method to retry up to
398
- # three times to avoid failing the entire test pipeline due to a network blip
399
- retry_opts = {
400
- :desired_exit_codes => [0,2],
401
- :max_retries => 3,
402
- # Beakers retry_on method wants the verbose value to be a string, not a bool.
403
- :verbose => 'true'
404
- }
405
- retry_on(master, puppet("agent -t"), retry_opts)
421
+ if (node_group)
422
+ if( ! node_group['classes'].include?(klass))
423
+ node_group['classes'][klass] = {}
424
+ _console_dispatcher.create_new_node_group_model(node_group)
425
+
426
+ # The puppet agent run that will download the agent tarballs to the master can sometimes fail with
427
+ # curl errors if there is a network hiccup. Use beakers `retry_on` method to retry up to
428
+ # three times to avoid failing the entire test pipeline due to a network blip
429
+ retry_opts = {
430
+ :desired_exit_codes => [0,2],
431
+ :max_retries => 3,
432
+ # Beakers retry_on method wants the verbose value to be a string, not a bool.
433
+ :verbose => 'true'
434
+ }
435
+ retry_on(master, puppet("agent -t"), retry_opts)
436
+
437
+ # Download the agent tarballs to compile masters
438
+ hosts.each do |h|
439
+ if h['roles'].include?('compile_master')
440
+ retry_on(h, puppet("agent -t"), retry_opts)
441
+ end
442
+ end
443
+ end
444
+ else
445
+ raise "Failed to add pe_repo packages, PE Master node group is not available"
406
446
  end
407
447
  end
408
448
  end
@@ -598,16 +638,24 @@ module Beaker
598
638
 
599
639
  if agent_only_check_needed && hosts_agent_only.include?(host) || install_via_msi?(host)
600
640
  host['type'] = 'aio'
601
- install_puppet_agent_pe_promoted_repo_on(host, {
641
+ install_params = {
602
642
  :puppet_agent_version => get_puppet_agent_version(host, opts),
603
643
  :puppet_agent_sha => host[:puppet_agent_sha] || opts[:puppet_agent_sha],
604
644
  :pe_ver => host[:pe_ver] || opts[:pe_ver],
605
- :puppet_collection => host[:puppet_collection] || opts[:puppet_collection]
606
- })
645
+ :puppet_collection => host[:puppet_collection] || opts[:puppet_collection],
646
+ :pe_promoted_builds_url => host[:pe_promoted_builds_url] || opts[:pe_promoted_builds_url]
647
+ }
648
+ install_params.delete(:pe_promoted_builds_url) if install_params[:pe_promoted_builds_url].nil?
649
+ install_puppet_agent_pe_promoted_repo_on(host, install_params)
607
650
  # 1 since no certificate found and waitforcert disabled
608
651
  acceptable_exit_codes = [0, 1]
609
652
  acceptable_exit_codes << 2 if opts[:type] == :upgrade
610
- setup_defaults_and_config_helper_on(host, master, acceptable_exit_codes)
653
+ if masterless
654
+ configure_type_defaults_on(host)
655
+ on host, puppet_agent('-t'), :acceptable_exit_codes => acceptable_exit_codes
656
+ else
657
+ setup_defaults_and_config_helper_on(host, master, acceptable_exit_codes)
658
+ end
611
659
  #Windows allows frictionless installs starting with PE Davis, if frictionless we need to skip this step
612
660
  elsif (host['platform'] =~ /windows/ && !(host['roles'].include?('frictionless')) || install_via_msi?(host))
613
661
  opts = { :debug => host[:pe_debug] || opts[:pe_debug] }
@@ -1541,6 +1589,34 @@ module Beaker
1541
1589
  end
1542
1590
  end
1543
1591
  end
1592
+
1593
+ # Method to install just the agent nodes
1594
+ # This method can be called only after installing PE on all other nodes
1595
+ # including infrastructure nodes, loadbalancer, hubs and spokes
1596
+ # PE-22051
1597
+ # @param [Array] agent only nodes from Beaker hosts
1598
+ # @param [Hash] opts The Beaker options hash
1599
+ #
1600
+ def install_agents_only_on(agentnodes, opts)
1601
+ if( ! agentnodes.empty?)
1602
+ configure_type_defaults_on(agentnodes)
1603
+ agentnodes.each do |host|
1604
+ if host['platform'] != master['platform']
1605
+ deploy_frictionless_to_master(host)
1606
+ end
1607
+ install_ca_cert_on(host, opts)
1608
+ on(host, installer_cmd(host, opts))
1609
+ end
1610
+ sign_certificate_for(agentnodes)
1611
+ stop_agent_on(agentnodes, :run_in_parallel => true)
1612
+ on agentnodes, puppet_agent('-t'), :acceptable_exit_codes => [0,2], :run_in_parallel => true
1613
+ agentnodes.select {|agent| agent['platform'] =~ /windows/}.each do |agent|
1614
+ client_datadir = agent.puppet['client_datadir']
1615
+ on(agent, puppet("resource file \"#{client_datadir}\" ensure=absent force=true"))
1616
+ end
1617
+ end
1618
+ end
1619
+
1544
1620
  end
1545
1621
  end
1546
1622
  end
@@ -3,7 +3,7 @@ module Beaker
3
3
  module PE
4
4
 
5
5
  module Version
6
- STRING = '1.23.0'
6
+ STRING = '1.24.0'
7
7
  end
8
8
 
9
9
  end
@@ -60,6 +60,17 @@ describe ClassMixedWithDSLInstallUtils do
60
60
  :working_dir => '/tmp',
61
61
  :dist => 'puppet-enterprise-3.7.1-rc0-78-gffc958f-eos-4-i386' } ) }
62
62
 
63
+ let(:lei_hosts) { make_hosts( { :pe_ver => '3.0',
64
+ :platform => 'linux',
65
+ :roles => [ 'agent' ],
66
+ :type => 'pe'}, 4 ) }
67
+ let(:lb_test_hosts) { lei_hosts[0][:roles] = ['master', 'database', 'dashboard']
68
+ lei_hosts[1][:roles] = ['loadbalancer', 'lb_connect']
69
+ lei_hosts[2][:roles] = ['compile_master']
70
+ lei_hosts[3][:roles] = ['frictionless', 'lb_connect']
71
+ lei_hosts[3][:working_dir] = '/tmp'
72
+ lei_hosts }
73
+
63
74
  context '#prep_host_for_upgrade' do
64
75
 
65
76
  it 'sets per host options before global options' do
@@ -188,6 +199,22 @@ describe ClassMixedWithDSLInstallUtils do
188
199
  end
189
200
  end
190
201
 
202
+ describe 'loadbalancer_connecting_agents' do
203
+ it 'no hosts are chosen if there are no agents with lb_connect role' do
204
+ allow( subject ).to receive(:hosts).and_return([])
205
+ end
206
+ it 'chooses agents with lb_connect role' do
207
+ allow( subject ).to receive(:lb_test_hosts).and_return([lb_test_hosts[3]])
208
+ end
209
+
210
+ end
211
+
212
+ describe 'get_lb_downloadhost' do
213
+ it 'choose lb_connect loadbalancer, if there is one' do
214
+ allow( subject ).to receive(:lb_test_hosts[3]).and_return([lb_test_hosts[1]])
215
+ end
216
+ end
217
+
191
218
  describe 'frictionless_agent_installer_cmd' do
192
219
  let(:host) do
193
220
  the_host = unixhost.dup
@@ -265,6 +292,18 @@ describe ClassMixedWithDSLInstallUtils do
265
292
  "\""
266
293
  expect( subject.frictionless_agent_installer_cmd( host, {}, '2016.4.0' ) ).to eq(expecting)
267
294
  end
295
+
296
+ it 'generates a frictionless install command with loadbalancer as download host' do
297
+ hosts = lb_test_hosts
298
+ expect( subject ).to receive( :get_lb_downloadhost ).with(lb_test_hosts[3]).and_return( 'testloadbalancer' )
299
+ expecting = [
300
+ "FRICTIONLESS_TRACE='true'",
301
+ "export FRICTIONLESS_TRACE",
302
+ "cd /tmp && curl --tlsv1 -O -k https://testloadbalancer:8140/packages/current/install.bash && bash install.bash"
303
+ ].join("; ")
304
+
305
+ expect( subject.frictionless_agent_installer_cmd( lb_test_hosts[3], {}, '2016.4.0' ) ).to eq(expecting)
306
+ end
268
307
  end
269
308
 
270
309
  describe 'install_ca_cert_on' do
@@ -1079,8 +1118,14 @@ describe ClassMixedWithDSLInstallUtils do
1079
1118
  describe '#deploy_frictionless_to_master' do
1080
1119
  let(:master) { make_host('master', :pe_ver => '2017.2', :platform => 'ubuntu-16.04-x86_64', :roles => ['master', 'database', 'dashboard']) }
1081
1120
  let(:agent) { make_host('agent', :pe_ver => '2017.2', :platform => 'el-7-x86_64', :roles => ['frictionless']) }
1121
+ let(:compile_master) { make_host('agent', :pe_ver => '2017.2', :roles => ['frictionless', 'compile_master']) }
1082
1122
  let(:dispatcher) { double('dispatcher') }
1083
- let(:node_group) { {} }
1123
+ let(:node_group) do
1124
+ {
1125
+ 'classes' => {
1126
+ },
1127
+ }
1128
+ end
1084
1129
 
1085
1130
  before :each do
1086
1131
  allow(subject).to receive(:retry_on)
@@ -1090,12 +1135,12 @@ describe ClassMixedWithDSLInstallUtils do
1090
1135
 
1091
1136
  allow(dispatcher).to receive(:get_node_group_by_name).and_return(node_group)
1092
1137
  allow(dispatcher).to receive(:create_new_node_group_model) {|model| node_group.update(model)}
1138
+ allow(subject).to receive(:compile_masters).and_return([compile_master])
1093
1139
  end
1094
1140
 
1095
- it 'adds the right pe_repo class to the Beaker Frictionless Agent group' do
1141
+ it 'adds the right pe_repo class to the PE Master group' do
1096
1142
  subject.deploy_frictionless_to_master(agent)
1097
1143
 
1098
- expect(node_group['rule']).to eq(['and', ['=', 'name', 'master']])
1099
1144
  expect(node_group['classes']).to include('pe_repo::platform::el_7_x86_64')
1100
1145
  end
1101
1146
 
@@ -1216,10 +1261,12 @@ describe ClassMixedWithDSLInstallUtils do
1216
1261
  hosts = make_hosts({
1217
1262
  :pe_ver => '4.0',
1218
1263
  :roles => ['agent'],
1219
- }, 3)
1264
+ }, 4)
1220
1265
  hosts[0][:roles] = ['master', 'database', 'dashboard']
1221
1266
  hosts[1][:platform] = 'windows'
1222
1267
  hosts[2][:platform] = Beaker::Platform.new('el-6-x86_64')
1268
+ hosts[2][:pe_promoted_builds_url] = nil
1269
+ hosts[3][:pe_promoted_builds_url] = 'test-url'
1223
1270
 
1224
1271
  allow( subject ).to receive( :hosts ).and_return( hosts )
1225
1272
  allow( subject ).to receive( :options ).and_return(Beaker::Options::Presets.new.presets)
@@ -1248,19 +1295,29 @@ describe ClassMixedWithDSLInstallUtils do
1248
1295
  expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with(
1249
1296
  hosts[1],
1250
1297
  {
1251
- :puppet_agent_version => pa_version,
1252
- :puppet_agent_sha => nil,
1253
- :pe_ver => hosts[1][:pe_ver],
1254
- :puppet_collection => nil
1298
+ :puppet_agent_version => pa_version,
1299
+ :puppet_agent_sha => nil,
1300
+ :pe_ver => hosts[1][:pe_ver],
1301
+ :puppet_collection => nil,
1255
1302
  }
1256
1303
  ).once
1257
1304
  expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with(
1258
1305
  hosts[2],
1259
1306
  {
1260
- :puppet_agent_version => pa_version,
1261
- :puppet_agent_sha => nil,
1262
- :pe_ver => hosts[2][:pe_ver],
1263
- :puppet_collection => nil
1307
+ :puppet_agent_version => pa_version,
1308
+ :puppet_agent_sha => nil,
1309
+ :pe_ver => hosts[2][:pe_ver],
1310
+ :puppet_collection => nil,
1311
+ }
1312
+ ).once
1313
+ expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with(
1314
+ hosts[3],
1315
+ {
1316
+ :puppet_agent_version => pa_version,
1317
+ :puppet_agent_sha => nil,
1318
+ :pe_ver => hosts[3][:pe_ver],
1319
+ :puppet_collection => nil,
1320
+ :pe_promoted_builds_url => 'test-url'
1264
1321
  }
1265
1322
  ).once
1266
1323
  hosts.each do |host|
@@ -1325,7 +1382,7 @@ describe ClassMixedWithDSLInstallUtils do
1325
1382
  :puppet_agent_version => pa_version,
1326
1383
  :puppet_agent_sha => nil,
1327
1384
  :pe_ver => hosts[1][:pe_ver],
1328
- :puppet_collection => nil
1385
+ :puppet_collection => nil,
1329
1386
  }
1330
1387
  ).once
1331
1388
  expect( subject ).to receive( :on ).with( hosts[2], /puppet-enterprise-installer/ ).once
@@ -1392,10 +1449,10 @@ describe ClassMixedWithDSLInstallUtils do
1392
1449
  allow( subject ).to receive(
1393
1450
  :install_puppet_agent_pe_promoted_repo_on
1394
1451
  ).with( hosts[1], {
1395
- :puppet_agent_version => pa_version,
1396
- :puppet_agent_sha => nil,
1397
- :pe_ver => hosts[1][:pe_ver],
1398
- :puppet_collection => nil
1452
+ :puppet_agent_version => pa_version,
1453
+ :puppet_agent_sha => nil,
1454
+ :pe_ver => hosts[1][:pe_ver],
1455
+ :puppet_collection => nil,
1399
1456
  } )
1400
1457
  # expect( subject ).to receive( :on ).with( hosts[2], /puppet-enterprise-installer/ ).once
1401
1458
  hosts.each do |host|
@@ -1446,6 +1503,22 @@ describe ClassMixedWithDSLInstallUtils do
1446
1503
  allow(subject).to receive(:sign_certificate_for)
1447
1504
  end
1448
1505
 
1506
+ describe 'install_agents_only_on' do
1507
+ let(:lb_agent) { make_host('agent', :pe_ver => '2016.4', :platform => 'debian-7-x86_64', :roles => ['frictionless', 'lb_connect']) }
1508
+
1509
+ before :each do
1510
+ allow(subject).to receive(:on)
1511
+ allow(subject).to receive(:configure_type_defaults_on)
1512
+ allow(subject).to receive(:deploy_frictionless_to_master)
1513
+ allow(subject).to receive(:install_agents_only_on)
1514
+
1515
+ allow(subject).to receive(:installer_cmd).with(lb_agent, anything()).and_return("install lb agent")
1516
+
1517
+ allow(subject).to receive(:stop_agent_on)
1518
+ allow(subject).to receive(:sign_certificate_for)
1519
+ end
1520
+ end
1521
+
1449
1522
  describe 'configuring frictionless installer' do
1450
1523
  it "skips the master's platform" do
1451
1524
  expect(subject).not_to receive(:deploy_frictionless_to_master)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beaker-pe
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.23.0
4
+ version: 1.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppetlabs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-15 00:00:00.000000000 Z
11
+ date: 2017-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -227,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
227
  version: '0'
228
228
  requirements: []
229
229
  rubyforge_project:
230
- rubygems_version: 2.4.6
230
+ rubygems_version: 2.4.8
231
231
  signing_key:
232
232
  specification_version: 4
233
233
  summary: Beaker PE DSL Helpers!