beaker 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,6 +10,9 @@ module Beaker
10
10
  # @return [Hash] A hash (keyed from hosts) containing hashes of answer file
11
11
  # data.
12
12
  def generate_answers
13
+ masterless = @options[:masterless]
14
+ return super if masterless
15
+
13
16
  dashboard = only_host_with_role(@hosts, 'dashboard')
14
17
  database = only_host_with_role(@hosts, 'database')
15
18
  master = only_host_with_role(@hosts, 'master')
@@ -6,6 +6,9 @@ module Beaker
6
6
  # @api private
7
7
  class Version34 < Version32
8
8
  def generate_answers
9
+ masterless = @options[:masterless]
10
+ return super if masterless
11
+
9
12
  dashboard = only_host_with_role(@hosts, 'dashboard')
10
13
  database = only_host_with_role(@hosts, 'database')
11
14
 
@@ -35,7 +38,7 @@ module Beaker
35
38
 
36
39
  # If we're installing or upgrading from a non-RBAC version, set the 'admin' password
37
40
  if @options[:type] == :upgrade && @options[:HOSTS][dashboard.name][:pe_ver] < "3.4.0"
38
- dashboard_password = "'#{options[:answers][:q_puppet_enterpriseconsole_auth_password]}'"
41
+ dashboard_password = "'#{@options[:answers][:q_puppet_enterpriseconsole_auth_password]}'"
39
42
  the_answers[dashboard.name][:q_puppet_enterpriseconsole_auth_password] = dashboard_password
40
43
  end
41
44
 
@@ -1256,7 +1256,8 @@ module Beaker
1256
1256
  avoid_puppet_at_all_costs ||= agent['pe_ver'] && version_is_less(agent['pe_ver'], '3.2') && agent['platform'] =~ /sles/
1257
1257
 
1258
1258
  if avoid_puppet_at_all_costs
1259
- on agent, "/etc/init.d/#{agent_service} stop"
1259
+ # When upgrading, puppet is already stopped. On EL4, this causes an exit code of '1'
1260
+ on agent, "/etc/init.d/#{agent_service} stop", :acceptable_exit_codes => [0, 1]
1260
1261
  else
1261
1262
  on agent, puppet_resource('service', agent_service, 'ensure=stopped')
1262
1263
  end
@@ -1354,6 +1355,46 @@ module Beaker
1354
1355
  on host, "curl %s" % cmd, opts, &block
1355
1356
  end
1356
1357
  end
1358
+
1359
+ # Write hiera config file on one or more provided hosts
1360
+ #
1361
+ # @param[Host, Array<Host>, String, Symbol] host One or more hosts to act upon,
1362
+ # or a role (String or Symbol) that identifies one or more hosts.
1363
+ # @param[Array] One or more hierarchy paths
1364
+ def write_hiera_config_on(host, hierarchy)
1365
+
1366
+ block_on host do |host|
1367
+ hiera_config=Hash.new
1368
+ hiera_config[:backends] = 'yaml'
1369
+ hiera_config[:yaml] = {}
1370
+ hiera_config[:yaml][:datadir] = host[:hieradatadir]
1371
+ hiera_config[:hierarchy] = hierarchy
1372
+ hiera_config[:logger] = 'console'
1373
+ create_remote_file host, host[:hieraconf], hiera_config.to_yaml
1374
+ end
1375
+ end
1376
+
1377
+ # Write hiera config file for the default host
1378
+ # @see #write_hiera_config_on
1379
+ def write_hiera_config(hierarchy)
1380
+ write_hiera_config_on(default, hierarchy)
1381
+ end
1382
+
1383
+ # Copy hiera data files to one or more provided hosts
1384
+ #
1385
+ # @param[Host, Array<Host>, String, Symbol] host One or more hosts to act upon,
1386
+ # or a role (String or Symbol) that identifies one or more hosts.
1387
+ # @param[String] Directory containing the hiera data files.
1388
+ def copy_hiera_data_to(host, source)
1389
+ scp_to host, File.expand_path(source), host[:hieradatadir]
1390
+ end
1391
+
1392
+ # Copy hiera data files to the default host
1393
+ # @see #copy_hiera_data_to
1394
+ def copy_hiera_data(source)
1395
+ copy_hiera_data_to(default, source)
1396
+ end
1397
+
1357
1398
  end
1358
1399
  end
1359
1400
  end
@@ -453,12 +453,16 @@ module Beaker
453
453
  # @api private
454
454
  #
455
455
  def do_install hosts, opts = {}
456
+ masterless = (defined? options) ? options[:masterless] : false
457
+ opts[:masterless] = masterless # has to pass masterless down for answer generation awareness
456
458
  opts[:type] = opts[:type] || :install
457
- pre30database = version_is_less(opts[:pe_ver] || database['pe_ver'], '3.0')
458
- pre30master = version_is_less(opts[:pe_ver] || master['pe_ver'], '3.0')
459
+ unless masterless
460
+ pre30database = version_is_less(opts[:pe_ver] || database['pe_ver'], '3.0')
461
+ pre30master = version_is_less(opts[:pe_ver] || master['pe_ver'], '3.0')
459
462
 
460
- unless version_is_less(opts[:pe_ver] || master['pe_ver'], '3.4')
461
- master['puppetservice'] = 'pe-puppetserver'
463
+ unless version_is_less(opts[:pe_ver] || master['pe_ver'], '3.4')
464
+ master['puppetservice'] = 'pe-puppetserver'
465
+ end
462
466
  end
463
467
 
464
468
  # Set PE distribution for all the hosts, create working dir
@@ -489,9 +493,11 @@ module Beaker
489
493
 
490
494
  fetch_puppet(hosts, opts)
491
495
 
492
- # If we're installing a database version less than 3.0, ignore the database host
493
496
  install_hosts = hosts.dup
494
- install_hosts.delete(database) if pre30database and database != master and database != dashboard
497
+ unless masterless
498
+ # If we're installing a database version less than 3.0, ignore the database host
499
+ install_hosts.delete(database) if pre30database and database != master and database != dashboard
500
+ end
495
501
 
496
502
  install_hosts.each do |host|
497
503
  if host['platform'] =~ /windows/
@@ -511,7 +517,8 @@ module Beaker
511
517
  on host, puppet("config set server #{master}")
512
518
  on host, puppet("config set certname #{host}")
513
519
  #run once to request cert
514
- on host, puppet_agent('-t'), :acceptable_exit_codes => [1]
520
+ acceptable_codes = host['platform'] =~ /osx/ ? [1] : [0, 1]
521
+ on host, puppet_agent('-t'), :acceptable_exit_codes => acceptable_codes
515
522
  else
516
523
  answers = Beaker::Answers.create(opts[:pe_ver] || host['pe_ver'], hosts, opts)
517
524
  create_remote_file host, "#{host['working_dir']}/answers", answers.answer_string(host)
@@ -520,41 +527,43 @@ module Beaker
520
527
  end
521
528
 
522
529
  # On each agent, we ensure the certificate is signed then shut down the agent
523
- sign_certificate_for(host)
530
+ sign_certificate_for(host) unless masterless
524
531
  stop_agent_on(host)
525
532
  end
526
533
 
527
- # Wait for PuppetDB to be totally up and running (post 3.0 version of pe only)
528
- sleep_until_puppetdb_started(database) unless pre30database
534
+ unless masterless
535
+ # Wait for PuppetDB to be totally up and running (post 3.0 version of pe only)
536
+ sleep_until_puppetdb_started(database) unless pre30database
537
+
538
+ # Run the agent once to ensure everything is in the dashboard
539
+ install_hosts.each do |host|
540
+ on host, puppet_agent('-t'), :acceptable_exit_codes => [0,2]
541
+
542
+ # Workaround for PE-1105 when deploying 3.0.0
543
+ # The installer did not respect our database host answers in 3.0.0,
544
+ # and would cause puppetdb to be bounced by the agent run. By sleeping
545
+ # again here, we ensure that if that bounce happens during an upgrade
546
+ # test we won't fail early in the install process.
547
+ if host['pe_ver'] == '3.0.0' and host == database
548
+ sleep_until_puppetdb_started(database)
549
+ end
550
+ end
529
551
 
530
- # Run the agent once to ensure everything is in the dashboard
531
- install_hosts.each do |host|
532
- on host, puppet_agent('-t'), :acceptable_exit_codes => [0,2]
533
-
534
- # Workaround for PE-1105 when deploying 3.0.0
535
- # The installer did not respect our database host answers in 3.0.0,
536
- # and would cause puppetdb to be bounced by the agent run. By sleeping
537
- # again here, we ensure that if that bounce happens during an upgrade
538
- # test we won't fail early in the install process.
539
- if host['pe_ver'] == '3.0.0' and host == database
540
- sleep_until_puppetdb_started(database)
552
+ install_hosts.each do |host|
553
+ wait_for_host_in_dashboard(host)
541
554
  end
542
- end
543
555
 
544
- install_hosts.each do |host|
545
- wait_for_host_in_dashboard(host)
546
- end
556
+ if pre30master
557
+ task = 'nodegroup:add_all_nodes group=default'
558
+ else
559
+ task = 'defaultgroup:ensure_default_group'
560
+ end
561
+ on dashboard, "/opt/puppet/bin/rake -sf /opt/puppet/share/puppet-dashboard/Rakefile #{task} RAILS_ENV=production"
547
562
 
548
- if pre30master
549
- task = 'nodegroup:add_all_nodes group=default'
550
- else
551
- task = 'defaultgroup:ensure_default_group'
563
+ # Now that all hosts are in the dashbaord, run puppet one more
564
+ # time to configure mcollective
565
+ on install_hosts, puppet_agent('-t'), :acceptable_exit_codes => [0,2]
552
566
  end
553
- on dashboard, "/opt/puppet/bin/rake -sf /opt/puppet/share/puppet-dashboard/Rakefile #{task} RAILS_ENV=production"
554
-
555
- # Now that all hosts are in the dashbaord, run puppet one more
556
- # time to configure mcollective
557
- on install_hosts, puppet_agent('-t'), :acceptable_exit_codes => [0,2]
558
567
  end
559
568
 
560
569
  #Perform a Puppet Enterprise Higgs install up until web browser interaction is required, runs on linux hosts only.
@@ -620,7 +629,10 @@ module Beaker
620
629
  #
621
630
  # @!visibility private
622
631
  def sorted_hosts
623
- special_nodes = [master, database, dashboard].uniq
632
+ special_nodes = []
633
+ [master, database, dashboard].uniq.each do |host|
634
+ special_nodes << host if host != nil
635
+ end
624
636
  real_agents = agents - special_nodes
625
637
  special_nodes + real_agents
626
638
  end
@@ -815,10 +827,15 @@ module Beaker
815
827
  # @return nil
816
828
  # @api private
817
829
  def install_puppet_from_dmg( host, opts )
830
+
818
831
  puppet_ver = opts[:version]
819
832
  facter_ver = opts[:facter_version]
820
833
  hiera_ver = opts[:hiera_version]
821
834
 
835
+ if [puppet_ver, facter_ver, hiera_ver].include?(nil)
836
+ raise "You need to specify versions for OSX host\n eg. install_puppet({:version => '3.6.2',:facter_version => '2.1.0',:hiera_version => '1.3.4',})"
837
+ end
838
+
822
839
  on host, "curl -O #{opts[:mac_download_url]}/puppet-#{puppet_ver}.dmg"
823
840
  on host, "curl -O #{opts[:mac_download_url]}/facter-#{facter_ver}.dmg"
824
841
  on host, "curl -O #{opts[:mac_download_url]}/hiera-#{hiera_ver}.dmg"
@@ -1113,6 +1130,30 @@ module Beaker
1113
1130
  end
1114
1131
  end
1115
1132
 
1133
+ # Installs packages from the local development repository on the given host
1134
+ #
1135
+ # @param [Host] host An object implementing {Beaker::Hosts}'s
1136
+ # interface.
1137
+ # @param [Regexp] package_name The name of the package whose repository is
1138
+ # being installed.
1139
+ #
1140
+ # @note This method only works on redhat-like and debian-like hosts.
1141
+ # @note This method is paired to be run directly after {#install_puppetlabs_dev_repo}
1142
+ #
1143
+ def install_packages_from_local_dev_repo( host, package_name )
1144
+ if host['platform'] =~ /debian|ubuntu|cumulus/
1145
+ find_filename = '*.deb'
1146
+ find_command = 'dpkg -i'
1147
+ elsif host['platform'] =~ /fedora|el|centos/
1148
+ find_filename = '*.rpm'
1149
+ find_command = 'rpm -ivh'
1150
+ else
1151
+ raise "No repository installation step for #{host['platform']} yet..."
1152
+ end
1153
+ find_command = "find /root/#{package_name} -type f -name '#{find_filename}' -exec #{find_command} {} \\;"
1154
+ on host, find_command
1155
+ end
1156
+
1116
1157
  # Install development repo of the puppet-agent on the given host
1117
1158
  #
1118
1159
  # @param [Host] host An object implementing {Beaker::Hosts}'s interface
@@ -31,10 +31,11 @@ module Beaker
31
31
 
32
32
  # The host for which ['roles'] include 'master'.
33
33
  # If no host has the 'master' role, then use the host defined as 'default'.
34
- # If no host is defined as a 'master' and there is no 'default' host defined then
35
- # raise an error.
34
+ # If no host is defined as a 'master' and there is no 'default' host defined
35
+ # then it either raises an error (has a master),
36
+ # or it returns nil (masterless)
36
37
  #
37
- # @return [Array<Host>]
38
+ # @return [Host] Returns the host, or nil if not found & masterless
38
39
  # @raise [Beaker::DSL::Outcomes::FailTest] if there are less
39
40
  # or more than 1 master is found.
40
41
  #
@@ -42,33 +43,33 @@ module Beaker
42
43
  # on, master, 'cat /etc/puppet/puppet.conf'
43
44
  #
44
45
  def master
45
- find_only_one :master
46
+ find_host_with_role :master
46
47
  end
47
48
 
48
49
  # The host for which ['roles'] include 'database'
49
50
  #
50
- # @return [Array<Host>]
51
- # @raise [Beaker::DSL::Outcomes::FailTest] if there are less
52
- # or more than 1 database is found.
51
+ # @return [Host] Returns the host, or nil if not found & masterless
52
+ # @raise [Beaker::DSL::Outcomes::FailTest] if there are an inappropriate
53
+ # number of hosts found (depends on masterless option)
53
54
  #
54
55
  # @example Basic usage
55
56
  # on, agent, "curl -k http://#{database}:8080"
56
57
  #
57
58
  def database
58
- find_only_one :database
59
+ find_host_with_role :database
59
60
  end
60
61
 
61
62
  # The host for which ['roles'] include 'dashboard'
62
63
  #
63
- # @return [Array<Host>]
64
- # @raise [Beaker::DSL::Outcomes::FailTest] if there are less
65
- # or more than 1 dashboard is found.
64
+ # @return [Host] Returns the host, or nil if not found & masterless
65
+ # @raise [Beaker::DSL::Outcomes::FailTest] if there are an inappropriate
66
+ # number of hosts found (depends on masterless option)
66
67
  #
67
68
  # @example Basic usage
68
69
  # on, agent, "curl https://#{database}/nodes/#{agent}"
69
70
  #
70
71
  def dashboard
71
- find_only_one :dashboard
72
+ find_host_with_role :dashboard
72
73
  end
73
74
 
74
75
  # The default host
@@ -78,14 +79,15 @@ module Beaker
78
79
  # OR
79
80
  # - host with 'master' as a role
80
81
  #
81
- # @return [Array<Host>]
82
- # @raise [Beaker::DSL::Outcomes::FailTest] if no default host is found
82
+ # @return [Host] Returns the host, or nil if not found & masterless
83
+ # @raise [Beaker::DSL::Outcomes::FailTest] if there are an inappropriate
84
+ # number of hosts found (depends on masterless option)
83
85
  #
84
86
  # @example Basic usage
85
87
  # on, default, "curl https://#{database}/nodes/#{agent}"
86
88
  #
87
89
  def default
88
- find_only_one :default
90
+ find_host_with_role :default
89
91
  end
90
92
 
91
93
  #Create a new role method for a given arbitrary role name. Makes it possible to be able to run
@@ -147,6 +149,22 @@ module Beaker
147
149
  hosts_with_role(hosts, desired_role)
148
150
  end
149
151
 
152
+ # finds the appropriate number of hosts for a given role
153
+ # determines whether to allow no server using the masterless option
154
+ #
155
+ # @param [Symbol, String] role The role to find a host for
156
+ # @return [Host] Returns the host, or nil if masterless and none are found
157
+ # for that role
158
+ # @raise Throws an exception if an inappropriate number of hosts are found
159
+ # for that role
160
+ def find_host_with_role role
161
+ if (defined? options) && options[:masterless]
162
+ find_at_most_one role
163
+ else
164
+ find_only_one role
165
+ end
166
+ end
167
+
150
168
  # @param [Symbol, String] role The role to find a host for
151
169
  # @return [Host] Returns the host, if one and only one is found
152
170
  # @raise Raises a failure exception if one and only one host that matches
@@ -156,6 +174,16 @@ module Beaker
156
174
  rescue ArgumentError => e
157
175
  raise DSL::Outcomes::FailTest, e.to_s
158
176
  end
177
+
178
+ # @param [Symbol, String] role The role to find a host for
179
+ # @return [Host] Returns the host, or nil if not found
180
+ # @raise Raises a failure exception if more than one host that matches
181
+ # the specified role is found.
182
+ def find_at_most_one role
183
+ find_at_most_one_host_with_role(hosts, role)
184
+ rescue ArgumentError => e
185
+ raise DSL::Outcomes::FailTest, e.to_s
186
+ end
159
187
  end
160
188
  end
161
189
  end
data/lib/beaker/host.rb CHANGED
@@ -49,6 +49,7 @@ module Beaker
49
49
  # related through 'type' and the differences between the assumption of our two
50
50
  # configurations we have for many of our products
51
51
  type = @options.get_type
52
+ type = :foss if type == :aio && !@options['HOSTS'][@name]['roles'].include?('agent')
52
53
  @defaults = merge_defaults_for_type @options, type
53
54
  pkg_initialize
54
55
  end
@@ -227,7 +227,7 @@ module Beaker
227
227
  # @param [Hash{Symbol=>String}] opts Options to alter execution.
228
228
  # @option opts [Boolean] :debug If true, print verbose rpm information when installing EPEL
229
229
  # @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
230
- # @option opts [String] :epel_url Link to download from
230
+ # @option opts [String] :epel_url Link to download from
231
231
  # @option opts [String] :epel_arch Architecture of epel to download (i386, x86_64, etc)
232
232
  # @option opts [String] :epel_6_pkg Package to download from provided link for el-6
233
233
  # @option opts [String] :epel_5_pkg Package to download from provided link for el-5
@@ -299,6 +299,8 @@ module Beaker
299
299
  if host['platform'] =~ /windows/
300
300
  host.exec(Command.new('cp -r .ssh /cygdrive/c/Users/Administrator/.'))
301
301
  host.exec(Command.new('chown -R Administrator /cygdrive/c/Users/Administrator/.ssh'))
302
+ elsif host['platform'] =~ /osx/
303
+ host.exec(Command.new('sudo cp -r .ssh /var/root/.'), {:pty => true})
302
304
  else
303
305
  host.exec(Command.new('sudo su -c "cp -r .ssh /root/."'), {:pty => true})
304
306
  end
@@ -332,13 +334,17 @@ module Beaker
332
334
  block_on host do |host|
333
335
  logger.debug "Update /etc/ssh/sshd_config to allow root login"
334
336
  # note: this sed command only works on gnu sed
335
- host.exec(Command.new("sudo su -c \"sed -ri 's/^#?PermitRootLogin no|^#?PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config\""), {:pty => true}
336
- )
337
+ if host['platform'] =~ /osx/
338
+ host.exec(Command.new("sudo sed -i '' 's/#PermitRootLogin no/PermitRootLogin Yes/g' /etc/sshd_config"))
339
+ host.exec(Command.new("sudo sed -i '' 's/#PermitRootLogin yes/PermitRootLogin Yes/g' /etc/sshd_config"))
340
+ else
341
+ host.exec(Command.new("sudo su -c \"sed -ri 's/^#?PermitRootLogin no|^#?PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config\""), {:pty => true})
342
+ end
337
343
  #restart sshd
338
344
  if host['platform'] =~ /debian|ubuntu|cumulus/
339
345
  host.exec(Command.new("sudo su -c \"service ssh restart\""), {:pty => true})
340
346
  elsif host['platform'] =~ /centos|el-|redhat|fedora|eos/
341
- host.exec(Command.new("sudo -E /sbin/service sshd restart"))
347
+ host.exec(Command.new("sudo -E /sbin/service sshd restart"), {:pty => true})
342
348
  else
343
349
  @logger.warn("Attempting to update ssh on non-supported platform: #{host.name}: #{host['platform']}")
344
350
  end
@@ -238,8 +238,8 @@ module Beaker
238
238
  @hosts.each do |host|
239
239
  amitype = host['vmname'] || host['platform']
240
240
  amisize = host['amisize'] || 'm1.small'
241
- subnet_id = host['subnet_id'] || nil
242
- vpc_id = host['vpc_id'] || nil
241
+ subnet_id = host['subnet_id'] || @options['subnet_id'] || nil
242
+ vpc_id = host['vpc_id'] || @options['vpc_id'] || nil
243
243
 
244
244
  if vpc_id and !subnet_id
245
245
  raise RuntimeError, "A subnet_id must be provided with a vpc_id"
@@ -256,7 +256,18 @@ module Beaker
256
256
  # Main region object for ec2 operations
257
257
  region = @ec2.regions[ami_region]
258
258
 
259
- # Obtain the VPC object if it exists
259
+ # If we haven't defined a vpc_id then we use the default vpc for the provided region
260
+ if !vpc_id
261
+ @logger.notify("aws-sdk: filtering available vpcs in region by 'isDefault")
262
+ filtered_vpcs = region.client.describe_vpcs(:filters => [{:name => 'isDefault', :values => ['true']}])
263
+ if !filtered_vpcs[:vpc_set].empty?
264
+ vpc_id = filtered_vpcs[:vpc_set].first[:vpc_id]
265
+ else #there's no default vpc, use nil
266
+ vpc_id = nil
267
+ end
268
+ end
269
+
270
+ # Grab the vpc object based upon provided id
260
271
  vpc = vpc_id ? region.vpcs[vpc_id] : nil
261
272
 
262
273
  # Grab image object
@@ -276,6 +287,8 @@ module Beaker
276
287
  block_device_mappings << {
277
288
  :device_name => device_name,
278
289
  :ebs => {
290
+ # Change the default size of the root volume.
291
+ :volume_size => host['volume_size'] || rest[:volume_size],
279
292
  # This is required to override the images default for
280
293
  # delete_on_termination, forcing all volumes to be deleted once the
281
294
  # instance is terminated.
@@ -284,6 +297,8 @@ module Beaker
284
297
  }
285
298
  end
286
299
 
300
+ security_group = ensure_group(vpc || region, Beaker::EC2Helper.amiports(host))
301
+
287
302
  # Launch the node, filling in the blanks from previous work.
288
303
  @logger.notify("aws-sdk: Launch instance")
289
304
  config = {
@@ -291,7 +306,7 @@ module Beaker
291
306
  :image_id => image_id,
292
307
  :monitoring_enabled => true,
293
308
  :key_pair => ensure_key_pair(region),
294
- :security_groups => [ensure_group(vpc || region, Beaker::EC2Helper.amiports(host))],
309
+ :security_groups => [security_group],
295
310
  :instance_type => amisize,
296
311
  :disable_api_termination => false,
297
312
  :instance_initiated_shutdown_behavior => "terminate",
@@ -527,20 +542,20 @@ module Beaker
527
542
 
528
543
  # Return an existing group, or create new one
529
544
  #
530
- # Accepts a region or VPC as input for checking & creation.
545
+ # Accepts a VPC as input for checking & creation.
531
546
  #
532
- # @param rv [AWS::EC2::Region, AWS::EC2::VPC] the AWS region or vpc control object
547
+ # @param vpc [AWS::EC2::VPC] the AWS vpc control object
533
548
  # @param ports [Array<Number>] an array of port numbers
534
549
  # @return [AWS::EC2::SecurityGroup] created security group
535
550
  # @api private
536
- def ensure_group(rv, ports)
551
+ def ensure_group(vpc, ports)
537
552
  @logger.notify("aws-sdk: Ensure security group exists for ports #{ports.to_s}, create if not")
538
553
  name = group_id(ports)
539
554
 
540
- group = rv.security_groups.filter('group-name', name).first
555
+ group = vpc.security_groups.filter('group-name', name).first
541
556
 
542
557
  if group.nil?
543
- group = create_group(rv, ports)
558
+ group = create_group(vpc, ports)
544
559
  end
545
560
 
546
561
  group