From c6e6f7373cf70e2f76326346522db81f7677e1c4 Mon Sep 17 00:00:00 2001 From: Steve Jansen Date: Tue, 9 Sep 2014 22:18:29 -0400 Subject: [PATCH 1/3] README update --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f5074b6..1d4ea98 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ for your specified platform. Additional, optional overrides can be provided: image_id: [SERVER IMAGE ID] flavor_id: [SERVER FLAVOR ID] - server_name: [A UNIQUE SERVER NAME] + server_name: [A FRIENDLY SERVER NAME] public_key_path: [PATH TO YOUR PUBLIC SSH KEY] rackspace_region: [A VALID RACKSPACE DC/REGION] wait_for: [NUM OF SECONDS TO WAIT BEFORE TIMING OUT, DEFAULT 600] @@ -66,7 +66,9 @@ Some configs are also derived based on your .ssh directory, specifically the ## Contributing 1. Fork it -2. Create your feature branch (`git checkout -b my-new-feature`) +2. `bundle install` +3. Create your feature branch (`git checkout -b my-new-feature`) +4. `bundle exec rake` must pass 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create new Pull Request From 906a4ddb04d768b8278632ea86e39c942ecb943b Mon Sep 17 00:00:00 2001 From: Steve Jansen Date: Tue, 9 Sep 2014 22:21:28 -0400 Subject: [PATCH 2/3] optional `:servicenet` config setting The optional config setting `:servicenet` defaults to false. When true, the setting will use the first private address of the node instead of the first public address. The first private ip address should always be the ServiceNet interface (10.184.0.0/13 or 10.208.0.0/12). The ServiceNet interface may be preferrable when running kitchen on another Rackspace cloud server, like a Jenkins build server, or for customers with VPN access to ServiceNet. Using ServiceNet avoids bandwidth charges and may avoid changes to the PublicNet/RackConnect firewall rules to allow SSH connections to the kitchen test VMs from the public Internet. --- README.md | 1 + lib/kitchen/driver/rackspace.rb | 11 +++++- spec/kitchen/driver/rackspace_spec.rb | 49 ++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1d4ea98..f708cf1 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ for your specified platform. Additional, optional overrides can be provided: no_ssh_tcp_check_sleep: [NUM OF SECONDS TO SLEEP IF no_ssh_tcp_check IS SET] networks: [LIST OF RACKSPACE NETWORK UUIDS, DEFAULT PUBLICNET AND SERVICE NET] rackconnect_wait: ['true' IF USING RACKCONNECT TO WAIT FOR IT TO COMPLETE] + servicenet: ['true' IF USING THE SERVICENET IP ADDRESS TO CONNECT] You also have the option of providing some configs via environment variables: diff --git a/lib/kitchen/driver/rackspace.rb b/lib/kitchen/driver/rackspace.rb index 5652eb4..4f2d7f5 100644 --- a/lib/kitchen/driver/rackspace.rb +++ b/lib/kitchen/driver/rackspace.rb @@ -37,6 +37,7 @@ class Rackspace < Kitchen::Driver::SSHBase default_config :no_ssh_tcp_check, false default_config :no_ssh_tcp_check_sleep, 120 default_config :rackconnect_wait, false + default_config :servicenet, false default_config(:image_id) { |driver| driver.default_image } default_config(:server_name) { |driver| driver.default_name } default_config :networks, nil @@ -75,7 +76,7 @@ def create(state) server.wait_for { ready? } puts '(server ready)' rackconnect_check(server) if config[:rackconnect_wait] - state[:hostname] = server.public_ip_address + state[:hostname] = hostname(server) tcp_check(state) rescue Fog::Errors::Error, Excon::Errors::Error => ex raise ActionFailed, ex.message @@ -156,6 +157,14 @@ def rackconnect_check(server) server.update # refresh accessIPv4 with new IP end + def hostname(server) + if config[:servicenet] == false + server.public_ip_address + else + server.private_ip_address + end + end + def networks base_nets = %w( 00000000-0000-0000-0000-000000000000 diff --git a/spec/kitchen/driver/rackspace_spec.rb b/spec/kitchen/driver/rackspace_spec.rb index e82e5bc..38593f0 100644 --- a/spec/kitchen/driver/rackspace_spec.rb +++ b/spec/kitchen/driver/rackspace_spec.rb @@ -113,6 +113,10 @@ it 'defaults to not waiting for rackconnect' do expect(driver[:rackconnect_wait]).to eq(false) end + + it 'defaults to the public ip address' do + expect(driver[:servicenet]).to eq(false) + end end platforms = { @@ -143,7 +147,8 @@ server_name: 'puppy', rackspace_region: 'ord', wait_for: 1200, - rackconnect_wait: true + rackconnect_wait: true, + use_private_ip_address: true } let(:config) { config } @@ -223,7 +228,49 @@ driver.create(state) end end + end + + describe '#create and use_private_ip_address' do + let(:server) do + double(id: 'test123', + wait_for: true, + public_ip_address: '1.2.3.4', + private_ip_address: '10.9.8.7') + end + let(:driver) do + config[:servicenet] = true + d = Kitchen::Driver::Rackspace.new(config) + d.instance = instance + allow(d).to receive(:default_name).and_return('a_monkey!') + allow(d).to receive(:create_server).and_return(server) + allow(d).to receive(:tcp_check).and_return(true) + d + end + + context 'username and API key only provided' do + let(:config) do + { + rackspace_username: 'hello', + rackspace_api_key: 'world', + wait_for: 1200 + } + end + it 'generates a server name in the absence of one' do + driver.create(state) + expect(driver[:server_name]).to eq('a_monkey!') + end + + it 'gets a proper server ID' do + driver.create(state) + expect(state[:server_id]).to eq('test123') + end + + it 'gets a private ip as the hostname' do + driver.create(state) + expect(state[:hostname]).to eq('10.9.8.7') + end + end end describe '#destroy' do From b8f2c8ca3bb5e06b8da40cf72d0d1fe96636d4b9 Mon Sep 17 00:00:00 2001 From: Steve Jansen Date: Tue, 9 Sep 2014 22:33:07 -0400 Subject: [PATCH 3/3] add tests for the `:rackconnect_wait` config setting --- spec/kitchen/driver/rackspace_spec.rb | 63 ++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/spec/kitchen/driver/rackspace_spec.rb b/spec/kitchen/driver/rackspace_spec.rb index 38593f0..8c34fcf 100644 --- a/spec/kitchen/driver/rackspace_spec.rb +++ b/spec/kitchen/driver/rackspace_spec.rb @@ -230,6 +230,65 @@ end end + describe '#create and rackconnect_wait' do + let(:server) do + double(id: 'test123', + wait_for: true, + public_ip_address: '1.2.3.4', + private_ip_address: '10.9.8.7', + update: nil) + end + let(:driver) do + d = Kitchen::Driver::Rackspace.new(config) + d.instance = instance + allow(d).to receive(:default_name).and_return('a_monkey!') + allow(d).to receive(:create_server).and_return(server) + allow(d).to receive(:tcp_check).and_return(true) + d + end + + context 'username and API key only provided' do + let(:config) do + { + rackspace_username: 'hello', + rackspace_api_key: 'world', + wait_for: 1200, + rackconnect_wait: true + } + end + + it 'generates a server name in the absence of one' do + driver.create(state) + expect(driver[:server_name]).to eq('a_monkey!') + end + + it 'gets a proper server ID' do + driver.create(state) + expect(state[:server_id]).to eq('test123') + end + + it 'gets a proper hostname (IP)' do + driver.create(state) + expect(state[:hostname]).to eq('1.2.3.4') + end + + it 'calls tcp_check' do + expect(driver).to receive(:tcp_check) + driver.create(state) + end + + it 'calls rackconnect_check ' do + expect(driver).to receive(:rackconnect_check) + driver.create(state) + end + + it 'rackconnect_check waits for rackconnect_automation' do + expect(server).to receive(:wait_for) + driver.send(:rackconnect_check, server) + end + end + end + describe '#create and use_private_ip_address' do let(:server) do double(id: 'test123', @@ -238,7 +297,6 @@ private_ip_address: '10.9.8.7') end let(:driver) do - config[:servicenet] = true d = Kitchen::Driver::Rackspace.new(config) d.instance = instance allow(d).to receive(:default_name).and_return('a_monkey!') @@ -252,7 +310,8 @@ { rackspace_username: 'hello', rackspace_api_key: 'world', - wait_for: 1200 + wait_for: 1200, + servicenet: true } end