Skip to content

Commit

Permalink
Merge 7f8e077 into 35b15cd
Browse files Browse the repository at this point in the history
  • Loading branch information
JJ Asghar committed Oct 7, 2015
2 parents 35b15cd + 7f8e077 commit e0c16ad
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 54 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# 2.1.0.pre / 2015-XX-XX

### New Features

* PR [#106][] - The ability to bootstrap on only a private network paired with [@thomascate][] and [@BobbyRyterski][]

### Bug Fixes

* PR [#106][] - Updated the README with better formatting

# 2.0.0 / 2015-09-30

### New Features
Expand All @@ -16,7 +26,7 @@

### Improvements

* Updates to the readme PR [#102][] - from [@BobbyRyterski][]
* PR [#102][] - Updates to the readme - from [@BobbyRyterski][]

# 1.8.1 / 2015-07-22

Expand Down Expand Up @@ -172,6 +182,7 @@ certain specified NICs; via [@monsterzz][]
* Initial release! Woo!


[#106]: https://github.com/test-kitchen/kitchen-openstack/pull/106
[#104]: https://github.com/test-kitchen/kitchen-openstack/pull/104
[#102]: https://github.com/test-kitchen/kitchen-openstack/pull/102
[#100]: https://github.com/test-kitchen/kitchen-openstack/pull/100
Expand Down Expand Up @@ -213,6 +224,7 @@ certain specified NICs; via [@monsterzz][]
[#7]: https://github.com/test-kitchen/kitchen-openstack/pull/7
[#2]: https://github.com/test-kitchen/kitchen-openstack/pull/2

[@thomascate]: https://github.com/thomascate
[@jmahowald]: https://github.com/jmahowald
[@dpetzel]: https://github.com/dpetzel
[@BobbyRyterski]: https://github.com/BobbyRyterski
Expand Down
51 changes: 34 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,33 @@

An OpenStack Nova driver for Test Kitchen 1.0!

Shamelessly copied from [Fletcher Nichol](https://github.com/fnichol)'s
awesome work on an [EC2 driver](https://github.com/test-kitchen/kitchen-ec2),
and [Adam Leff](https://github.com/adamleff)'s
amazing work on an [VRO driver](https://github.com/chef-partners/kitchen-vro).
Shamelessly copied from [Fletcher Nichol](https://github.com/fnichol)'s awesome work on an [EC2 driver](https://github.com/test-kitchen/kitchen-ec2), and [Adam Leff](https://github.com/adamleff)'s amazing work on an [VRO driver](https://github.com/chef-partners/kitchen-vro).

## Installation

Add this line to your application's Gemfile:

gem 'kitchen-openstack'
```ruby
gem 'kitchen-openstack'
```

And then execute:

$ bundle
```bash
$ bundle
```

Or install it yourself as:

$ gem install kitchen-openstack
```bash
$ gem install kitchen-openstack
```

Or if using [chefdk](https://downloads.chef.io/chef-dk) install with:

$ chef gem install kitchen-openstack

```bash
$ chef gem install kitchen-openstack
```
## Usage

Provide, at a minimum, the required driver options in your `.kitchen.yml` file:
Expand Down Expand Up @@ -93,6 +97,7 @@ By default, a unique server name will be generated and the current user's SSH
key will be used (with an RSA key taking precedence over a DSA), though that
behavior can be overridden with additional options:

```yaml
server_name: [A UNIQUE SERVER NAME]
server_name_prefix: [STATIC PREFIX FOR RANDOM SERVER NAME]
private_key_path: [PATH TO YOUR PRIVATE SSH KEY]
Expand All @@ -105,7 +110,8 @@ behavior can be overridden with additional options:
openstack_region: [A VALID OPENSTACK REGION]
availability_zone: [AN OPENSTACK AVAILABILITY ZONE]
openstack_service_name: [YOUR OPENSTACK COMPUTE SERVICE NAME]
openstack_network_name: [YOUR OPENSTACK NETWORK NAME USED TO CONNECT]
openstack_network_name: [YOUR OPENSTACK NETWORK NAME USED TO CONNECT, SUCH AS A PRIVATE NETWORK ONLY]
server_wait: [DEFAULTS TO 0, BUT THIS SETS A WAIT SO YOUR VM IS IN A GOOD STATE BEFORE TRYING TO CONNECT]
security_groups:
- [A LIST OF...]
- [...SECURITY GROUPS TO JOIN]
Expand All @@ -123,16 +129,20 @@ behavior can be overridden with additional options:
availability_zone: [THE BLOCK STORAGE AVAILABILITY ZONE, DEFAULTS TO nova]
volume_type: [THE VOLUME TYPE, THIS IS OPTIONAL]
delete_on_termination: [WILL DELETE VOLUME ON INSTANCE DESTROY WHEN true, OTHERWISE SET TO false]
winrm_wait: [DEFAULTS TO 0, BUT THIS HELPS CONFIRM WINRM IS IN A GOOD STATE BEFORE TRYING TO CONNECT]
```

If a `server_name_prefix` is specified then this prefix will be used when
generating random names of the form `<NAME PREFIX>-<RANDOM STRING>` e.g.
`myproject-asdfghjk`. If both `server_name_prefix` and `server_name` are
specified then the `server_name` takes precedence.

`winrm_wait` is a workaround to deal with how WinRM comes up during machine
creation. With `cloud-init` running on most OpenStack instances having this
wait makes sure that the machine is in a good state to work with.
`server_wait` is a workaround to deal with how some VMs with `cloud-init`.
Some clouds need this some, most OpenStack instances don't. This is a stop gap
wait makes sure that the machine is in a good state to work with. Ideally the
transport layer in Test-Kitchen will have a more intelligent way to deal with this.
You may want to add this for **WinRM** instances due to the multiple restarts that
happen on creation and boot. A good default is `300` seconds to make sure it's
in a good state.

If a `key_name` is provided it will be used instead of any
`public_key_path` that is specified.
Expand All @@ -147,8 +157,10 @@ A specific `floating_ip` or the ID of a `floating_ip_pool` can be provided to
bind a floating IP to the node. Any floating IP will be the IP used for
Test Kitchen's SSH calls to the node.

```yaml
floating_ip: [A SPECIFIC FLOATING IP TO ASSIGN]
floating_ip_pool: [AN OPENSTACK POOL NAME TO ASSIGN THE NEXT IP FROM]
```

In some complex network scenarios you can have several IP addresses designated
as public or private. Use `public_ip_order` or `private_ip_order` to control
Expand All @@ -168,20 +180,23 @@ to use second `10.0.1.1` IP address you need to specify

```yaml
private_ip_order: 1

```
assuming that test network is configured as private.

The `network_ref` option can be specified as an exact id, an exact name,
or as a regular expression matching the name of the network. You can pass one

network_ref: MYNET1
```yaml
network_ref: MYNET1
```

or many networks

```yaml
network_ref:
- MYNET1
- MYNET2
```

The `openstack_network_name` is used to select IP address for SSH connection.
It's recommended to specify this option in case of multiple networks used for
Expand All @@ -190,7 +205,9 @@ instance to provide more control over network connectivity.
Please note that `network_ref` relies on Network Services (`Fog::Network`) and
it can be unavailable in your OpenStack installation.

disable_ssl_validation: true
```yaml
disable_ssl_validation: true
```

Only disable SSL cert validation if you absolutely know what you are doing,
but are stuck with an OpenStack deployment without valid SSL certs.
Expand Down
23 changes: 17 additions & 6 deletions lib/kitchen/driver/openstack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def create(state)
elsif config[:floating_ip_pool]
attach_ip_from_pool(server, config[:floating_ip_pool])
end
state[:hostname] = get_ip(server)
wait_for_server(state)
setup_ssh(server, state) if bourne_shell?
add_ohai_hint(state)
Expand Down Expand Up @@ -159,7 +160,6 @@ def get_bdm(config)

def create_server
server_def = init_configuration

if config[:network_ref]
networks = [].concat([config[:network_ref]])
server_def[:nics] = networks.flatten.map do |net|
Expand Down Expand Up @@ -303,14 +303,26 @@ def get_public_private_ips(server)
end

def get_ip(server)
unless config[:floating_ip].nil?
if config[:floating_ip]
debug "Using floating ip: #{config[:floating_ip]}"
return config[:floating_ip]
end

# make sure we have the latest info
info 'Waiting for network information to be available...'
begin
w = server.wait_for { !addresses.empty? }
debug "Waited #{w[:duration]} seconds for network information."
rescue Fog::Errors::TimeoutError
raise ActionFailed, 'Could not get network information (timed out)'
end

# should also work for private networks
if config[:openstack_network_name]
debug "Using configured net: #{config[:openstack_network_name]}"
return server.addresses[config[:openstack_network_name]].first['addr']
end

pub, priv = get_public_private_ips(server)
priv ||= server.ip_addresses unless pub
pub, priv = parse_ips(pub, priv)
Expand Down Expand Up @@ -381,10 +393,9 @@ def disable_ssl_validation
end

def wait_for_server(state)
state[:hostname] = get_ip(state)
if config[:winrm_wait]
info "Sleeping for #{config[:winrm_wait]} seconds to let WinRM start up..." # rubocop:disable Metrics/LineLength
countdown(config[:winrm_wait])
if config[:server_wait]
info "Sleeping for #{config[:server_wait]} seconds to let your server to start up..." # rubocop:disable Metrics/LineLength
countdown(config[:server_wait])
end
info 'Waiting for server to be ready...'
instance.transport.connection(state).wait_until_ready
Expand Down
2 changes: 1 addition & 1 deletion lib/kitchen/driver/openstack_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ module Kitchen
#
# @author Jonathan Hartman <j@p4nt5.com>
module Driver
OPENSTACK_VERSION = '2.0.0'
OPENSTACK_VERSION = '2.1.0.pre'
end
end
83 changes: 54 additions & 29 deletions spec/kitchen/driver/openstack_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@
allow(d).to receive(:do_ssh_setup).and_return(true)
allow(d).to receive(:sleep)
allow(d).to receive(:wait_for_ssh_key_access).and_return('SSH key authetication successful') # rubocop:disable Metrics/LineLength
allow(d).to receive(:disable_ssl_validation).and_return(false)
d
end

Expand All @@ -211,28 +212,6 @@
end
end

context 'when executed with a bourne shell' do
before do
allow(driver).to receive(:bourne_shell?).and_return(true)
end

it 'executes the ssh setup' do
expect(driver).to receive(:setup_ssh)
driver.create(state)
end
end

context 'when executed in a non-bourne shell' do
before do
allow(driver).to receive(:bourne_shell?).and_return(false)
end

it 'does not execute the ssh setup' do
expect(driver).not_to receive(:setup_ssh)
driver.create(state)
end
end

context 'when a server is already created' do
it 'does not create a new instance' do
state[:server_id] = '123'
Expand Down Expand Up @@ -874,7 +853,8 @@
double(addresses: addresses,
public_ip_addresses: public_ip_addresses,
private_ip_addresses: private_ip_addresses,
ip_addresses: ip_addresses)
ip_addresses: ip_addresses,
wait_for: { duration: 0 })
end

context 'both public and private IPs' do
Expand Down Expand Up @@ -930,15 +910,23 @@
end
end

context 'when a floating ip is provided' do
let(:config) { { floating_ip: '1.2.3.4' } }

it 'returns the floating ip and skips reloading' do
allow(driver).to receive(:config).and_return(config)

expect(server).to_not receive(:wait_for)
expect(driver.send(:get_ip, server)).to eq('1.2.3.4')
end
end

context 'an OpenStack deployment without the floating IP extension' do
let(:server) do
s = double('server')
allow(s).to receive(:addresses).and_return(addresses)
allow(s).to receive(:public_ip_addresses).and_raise(
before do
allow(server).to receive(:public_ip_addresses).and_raise(
Fog::Compute::OpenStack::NotFound)
allow(s).to receive(:private_ip_addresses).and_raise(
allow(server).to receive(:private_ip_addresses).and_raise(
Fog::Compute::OpenStack::NotFound)
s
end

context 'both public and private IPs in the addresses hash' do
Expand All @@ -955,6 +943,22 @@
end
end

context 'when openstack_network_name is provided' do
let(:addresses) do
{
'public' => [{ 'addr' => '6.6.6.6' }, { 'addr' => '7.7.7.7' }],
'private' => [{ 'addr' => '8.8.8.8' }, { 'addr' => '9.9.9.9' }]
}
end
let(:config) { { openstack_network_name: 'public' } }

it 'should respond with the first address from the addresses' do
allow(driver).to receive(:config).and_return(config)

expect(driver.send(:get_ip, server)).to eq('6.6.6.6')
end
end

context 'only public IPs in the address hash' do
let(:addresses) do
{ 'public' => [{ 'addr' => '6.6.6.6' }, { 'addr' => '7.7.7.7' }] }
Expand Down Expand Up @@ -984,6 +988,17 @@
expect { driver.send(:get_ip, server) }.to raise_error(expected)
end
end

context 'when network information is not found' do
before do
allow(server).to receive(:wait_for).and_raise(Fog::Errors::TimeoutError)
end

it 'raises an exception' do
expected = Kitchen::ActionFailed
expect { driver.send(:get_ip, server) }.to raise_error(expected)
end
end
end

describe '#parse_ips' do
Expand Down Expand Up @@ -1078,6 +1093,16 @@
.and_return(read)
end

context 'when executed in a non-bourne shell' do
before do
allow(driver).to receive(:bourne_shell?).and_return(false)
end

it 'does not execute the ssh setup' do
expect(driver).not_to receive(:setup_ssh)
end
end

it 'opens an SSH session to the server' do
expect(Fog::SSH).to receive(:new).with(state[:hostname],
'root',
Expand Down

0 comments on commit e0c16ad

Please sign in to comment.