diff --git a/lib/kitchen/driver/openstack.rb b/lib/kitchen/driver/openstack.rb index 2d3576e2..98749eb2 100644 --- a/lib/kitchen/driver/openstack.rb +++ b/lib/kitchen/driver/openstack.rb @@ -2,7 +2,7 @@ # # Author:: Jonathan Hartman () # -# Copyright (C) 2013, Jonathan Hartman +# Copyright (C) 2013-2015, Jonathan Hartman # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ require 'ipaddr' require 'socket' require 'ohai' +require_relative 'openstack/volume' module Kitchen module Driver @@ -131,7 +132,7 @@ def compute end def volume - OpenstackVolume.new + Volume.new end def get_bdm(config) @@ -374,47 +375,5 @@ def find_matching(collection, name) nil end end - - # A class to allow the Kitchen Openstack driver - # to use Openstack volumes - # - # @author Liam Haworth - class OpenstackVolume - def volume(openstack_server) - Fog::Volume.new(openstack_server) - end - - def volume_ready?(vol_id, os) - resp = volume(os).get_volume_details(vol_id) - status = resp[:body]['volume']['status'] - fail "Failed to make volume <#{vol_id}>" if status == 'error' - status == 'available' - end - - def create_volume(config, os) - opt = {} - bdm = config[:block_device_mapping] - vanilla_options = [:snapshot_id, :imageRef, :volume_type, - :source_volid, :availability_zone] - vanilla_options.select { |o| bdm[o] }.each do |key| - opt[key] = bdm[key] - end - resp = volume(os).create_volume("#{config[:server_name]}-volume", - "#{config[:server_name]} volume", - bdm[:volume_size], - opt) - vol_id = resp[:body]['volume']['id'] - sleep(1) until volume_ready?(vol_id, os) - vol_id - end - - def get_bdm(config, os) - bdm = config[:block_device_mapping] - bdm[:volume_id] = create_volume(config, os) if bdm[:make_volume] - bdm.delete_if { |k, _| k == :make_volume } - bdm.delete_if { |k, _| k == :snapshot_id } - bdm - end - end end end diff --git a/lib/kitchen/driver/openstack/volume.rb b/lib/kitchen/driver/openstack/volume.rb new file mode 100644 index 00000000..4b3397ac --- /dev/null +++ b/lib/kitchen/driver/openstack/volume.rb @@ -0,0 +1,68 @@ +# Encoding: UTF-8 +# +# Author:: Jonathan Hartman () +# +# Copyright (C) 2013-2015, Jonathan Hartman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fog' +require 'kitchen' + +module Kitchen + module Driver + class Openstack < Kitchen::Driver::SSHBase + # A class to allow the Kitchen Openstack driver + # to use Openstack volumes + # + # @author Liam Haworth + class Volume + def volume(openstack_server) + Fog::Volume.new(openstack_server) + end + + def volume_ready?(vol_id, os) + resp = volume(os).get_volume_details(vol_id) + status = resp[:body]['volume']['status'] + fail "Failed to make volume <#{vol_id}>" if status == 'error' + status == 'available' + end + + def create_volume(config, os) + opt = {} + bdm = config[:block_device_mapping] + vanilla_options = [:snapshot_id, :imageRef, :volume_type, + :source_volid, :availability_zone] + vanilla_options.select { |o| bdm[o] }.each do |key| + opt[key] = bdm[key] + end + resp = volume(os).create_volume("#{config[:server_name]}-volume", + "#{config[:server_name]} volume", + bdm[:volume_size], + opt) + vol_id = resp[:body]['volume']['id'] + sleep(1) until volume_ready?(vol_id, os) + vol_id + end + + def get_bdm(config, os) + bdm = config[:block_device_mapping] + bdm[:volume_id] = create_volume(config, os) if bdm[:make_volume] + bdm.delete_if { |k, _| k == :make_volume } + bdm.delete_if { |k, _| k == :snapshot_id } + bdm + end + end + end + end +end diff --git a/spec/kitchen/driver/openstack/volume_spec.rb b/spec/kitchen/driver/openstack/volume_spec.rb new file mode 100644 index 00000000..aa016bfc --- /dev/null +++ b/spec/kitchen/driver/openstack/volume_spec.rb @@ -0,0 +1,121 @@ +# Encoding: UTF-8 + +require_relative '../../../spec_helper' +require_relative '../../../../lib/kitchen/driver/openstack/volume' + +require 'logger' +require 'stringio' +require 'rspec' +require 'kitchen' +require 'ohai' + +describe Kitchen::Driver::Openstack::Volume do + let(:os) do + { + openstack_username: 'twilight', + openstack_api_key: 'sparkle', + openstack_auth_url: 'http:', + openstack_tenant: 'trixie', + openstack_region: 'syd', + openstack_service_name: 'the_service' + } + end + + describe '#volume' do + let(:vol_driver) do + described_class.new + end + + it 'creates a new block device connection' do + allow(Fog::Volume).to receive(:new) { |arg| arg } + expect(vol_driver.send(:volume, os)).to eq(os) + end + end + + describe '#volume_ready?' do + let(:volume_details) do + { + body: { 'volume' => { 'status' => 'available' } } + } + end + + let(:volume) do + double( + get_volume_details: volume_details + ) + end + + let(:vol_driver) do + d = described_class.new + allow(d).to receive(:volume).and_return(volume) + d + end + + it 'checks if the volume is ready' do + expect(vol_driver.send(:volume_ready?, '333', os)).to eq(true) + end + end + + describe '#create_volume' do + let(:config) do + { + server_name: 'applejack', + block_device_mapping: { + snapshot_id: '444', + volume_size: '5' + } + } + end + + let(:create_volume) do + { + body: { 'volume' => { 'id' => '555' } } + } + end + + let(:volume) do + double( + create_volume: create_volume + ) + end + + let(:vol_driver) do + d = described_class.new + allow(d).to receive(:volume).and_return(volume) + allow(d).to receive(:volume_ready?).and_return(true) + d + end + + it 'creates a volume' do + expect(vol_driver.send(:create_volume, config, os)).to eq('555') + end + end + + describe '#get_bdm' do + let(:config) do + { + block_device_mapping: { + make_volue: true, + snapshot_id: '333', + volume_id: '555', + volume_size: '5', + volume_device_name: 'vda', + delete_on_termination: true + } + } + end + + let(:vol_driver) do + d = described_class.new + allow(d).to receive(:create_volume).and_return('555') + d + end + + it 'returns the block device mapping config' do + expects = config[:block_device_mapping] + expects.delete_if { |k, _| k == :make_volume } + expects.delete_if { |k, _| k == :snapshot_id } + expect(vol_driver.send(:get_bdm, config, os)).to eq(expects) + end + end +end diff --git a/spec/kitchen/driver/openstack_spec.rb b/spec/kitchen/driver/openstack_spec.rb index a513632b..c6bff9bd 100644 --- a/spec/kitchen/driver/openstack_spec.rb +++ b/spec/kitchen/driver/openstack_spec.rb @@ -1,22 +1,7 @@ # Encoding: UTF-8 -# -# Author:: Jonathan Hartman () -# -# Copyright (C) 2013, Jonathan Hartman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. require_relative '../../spec_helper' +require_relative '../../../lib/kitchen/driver/openstack' require 'logger' require 'stringio' @@ -40,7 +25,7 @@ end let(:driver) do - d = Kitchen::Driver::Openstack.new(config) + d = described_class.new(config) d.instance = instance d end @@ -170,7 +155,7 @@ double(id: 'test123', wait_for: true, public_ip_addresses: %w(1.2.3.4)) end let(:driver) do - d = Kitchen::Driver::Openstack.new(config) + d = described_class.new(config) d.instance = instance allow(d).to receive(:default_name).and_return('a_monkey!') allow(d).to receive(:create_server).and_return(server) @@ -232,7 +217,7 @@ let(:compute) { double(servers: servers) } let(:driver) do - d = Kitchen::Driver::Openstack.new(config) + d = described_class.new(config) d.instance = instance allow(d).to receive(:compute).and_return(compute) d @@ -270,7 +255,7 @@ end let(:compute) { double(servers: servers) } let(:driver) do - d = Kitchen::Driver::Openstack.new(config) + d = described_class.new(config) d.instance = instance allow(d).to receive(:compute).and_return(compute) d @@ -417,7 +402,7 @@ } end let(:driver) do - d = Kitchen::Driver::Openstack.new(config) + d = described_class.new(config) d.instance = instance allow(d).to receive(:compute).and_return(compute) allow(d).to receive(:network).and_return(network) @@ -851,7 +836,7 @@ let(:ip_addresses) { nil } let(:parsed_ips) { [[], []] } let(:driver) do - d = Kitchen::Driver::Openstack.new(config) + d = described_class.new(config) d.instance = instance allow(d).to receive(:parse_ips).and_return(parsed_ips) d @@ -1148,114 +1133,3 @@ end end end - -describe Kitchen::Driver::OpenstackVolume do - let(:os) do - { - openstack_username: 'twilight', - openstack_api_key: 'sparkle', - openstack_auth_url: 'http:', - openstack_tenant: 'trixie', - openstack_region: 'syd', - openstack_service_name: 'the_service' - } - end - - describe '#volume' do - let(:vol_driver) do - Kitchen::Driver::OpenstackVolume.new - end - - it 'creates a new block device connection' do - allow(Fog::Volume).to receive(:new) { |arg| arg } - expect(vol_driver.send(:volume, os)).to eq(os) - end - end - - describe '#volume_ready?' do - let(:volume_details) do - { - body: { 'volume' => { 'status' => 'available' } } - } - end - - let(:volume) do - double( - get_volume_details: volume_details - ) - end - - let(:vol_driver) do - d = Kitchen::Driver::OpenstackVolume.new - allow(d).to receive(:volume).and_return(volume) - d - end - - it 'checks if the volume is ready' do - expect(vol_driver.send(:volume_ready?, '333', os)).to eq(true) - end - end - - describe '#create_volume' do - let(:config) do - { - server_name: 'applejack', - block_device_mapping: { - snapshot_id: '444', - volume_size: '5' - } - } - end - - let(:create_volume) do - { - body: { 'volume' => { 'id' => '555' } } - } - end - - let(:volume) do - double( - create_volume: create_volume - ) - end - - let(:vol_driver) do - d = Kitchen::Driver::OpenstackVolume.new - allow(d).to receive(:volume).and_return(volume) - allow(d).to receive(:volume_ready?).and_return(true) - d - end - - it 'creates a volume' do - expect(vol_driver.send(:create_volume, config, os)).to eq('555') - end - end - - describe '#get_bdm' do - let(:config) do - { - block_device_mapping: { - make_volue: true, - snapshot_id: '333', - volume_id: '555', - volume_size: '5', - volume_device_name: 'vda', - delete_on_termination: true - } - } - end - - let(:vol_driver) do - d = Kitchen::Driver::OpenstackVolume.new - allow(d).to receive(:create_volume).and_return('555') - d - end - - it 'returns the block device mapping config' do - expects = config[:block_device_mapping] - expects.delete_if { |k, _| k == :make_volume } - expects.delete_if { |k, _| k == :snapshot_id } - expect(vol_driver.send(:get_bdm, config, os)).to eq(expects) - end - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 28074685..0f54c4dc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,21 +1,4 @@ # Encoding: UTF-8 -# -# Author:: Jonathan Hartman () -# -# Copyright (C) 2013, Jonathan Hartman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# require 'rspec' require 'simplecov' @@ -31,5 +14,3 @@ SimpleCov.start do add_filter '/vendor/' end - -require_relative '../lib/kitchen/driver/openstack'