From 21a7a682e9c03ee46e18f2ee7aff0ebc61289703 Mon Sep 17 00:00:00 2001 From: Denis Egorenko Date: Wed, 30 Sep 2015 18:39:15 +0300 Subject: [PATCH] Rewrite nova_network provider with using only nova client Currently nova_network provider uses admin tool nova-manage for managing nova-networks, but this tool doesn't have any authentication and doesn't provide all features of nova client. This patch avoids problem with authentication by using nova client for managing networks. Another goal of this patch, with using nova client, is that all providers should use one way for authentication, based on openstack client and openstacklib [1] But the problem is that openstack client doesn't provide possibility to manage nova-networks. So, this provider will be used with nova client, until nova-network exists. Also added new tests. [1] blueprint use-openstackclient-in-module-resources Change-Id: I34c88ab9601b8b0bbf77588005422620eb575d6a --- lib/puppet/provider/nova_network/nova.rb | 43 +++++++++++ .../provider/nova_network/nova_manage.rb | 71 ------------------- spec/unit/provider/nova_network/nova_spec.rb | 63 ++++++++++++++++ 3 files changed, 106 insertions(+), 71 deletions(-) create mode 100644 lib/puppet/provider/nova_network/nova.rb delete mode 100644 lib/puppet/provider/nova_network/nova_manage.rb create mode 100644 spec/unit/provider/nova_network/nova_spec.rb diff --git a/lib/puppet/provider/nova_network/nova.rb b/lib/puppet/provider/nova_network/nova.rb new file mode 100644 index 000000000..64e194b9c --- /dev/null +++ b/lib/puppet/provider/nova_network/nova.rb @@ -0,0 +1,43 @@ +require File.join(File.dirname(__FILE__), '..','..','..', 'puppet/provider/nova') + +Puppet::Type.type(:nova_network).provide(:nova, :parent => Puppet::Provider::Nova) do + + desc "Manage nova network" + + optional_commands :nova => 'nova' + + def create + optional_opts = [] + { + # this needs to be converted from a project name to an id + :project => '--project_id', + :dns1 => '--dns1', + :dns2 => '--dns2', + :gateway => '--gateway', + :bridge => '--bridge', + :vlan_start => '--vlan-start', + :allowed_start => '--allowed-start', + :allowed_end => '--allowed-end', + }.each do |param, opt| + if resource[param] + optional_opts.push(opt).push(resource[param]) + end + end + + opts = [resource[:label], "--fixed-range-v4", resource[:name]] + + auth_nova('network-create', opts + optional_opts) + end + + def exists? + instances = auth_nova('network-list') + return instances.split('\n')[1..-1].detect do |n| + n =~ /(\S+)\s+(#{resource[:network]})\s+(\S+)/ + end + end + + def destroy + auth_nova("network-delete", resource[:network]) + end + +end diff --git a/lib/puppet/provider/nova_network/nova_manage.rb b/lib/puppet/provider/nova_network/nova_manage.rb deleted file mode 100644 index b89f61ef0..000000000 --- a/lib/puppet/provider/nova_network/nova_manage.rb +++ /dev/null @@ -1,71 +0,0 @@ -require File.join(File.dirname(__FILE__), '..','..','..', - 'puppet/provider/nova') - -Puppet::Type.type(:nova_network).provide(:nova_manage, :parent => Puppet::Provider::Nova) do - - desc "Manage nova network" - - optional_commands :nova_manage => 'nova-manage', :nova => 'nova' - - # I need to setup caching and what-not to make this lookup performance not suck - def self.instances - begin - network_list = nova_manage("network", "list") - rescue Exception => e - if e.message =~ /No networks defined/ - return [] - else - raise(e) - end - end - network_list.split("\n")[1..-1].collect do |net| - if net =~ /^(\S+)\s+(\S+)/ - new(:name => $2 ) - end - end.compact - end - - def create - optional_opts = [] - { - # this needs to be converted from a project name to an id - :project => '--project_id', - :dns1 => '--dns1', - :dns2 => '--dns2', - :gateway => '--gateway', - :bridge => '--bridge', - :vlan_start => '--vlan-start', - :allowed_start => '--allowed-start', - :allowed_end => '--allowed-end', - }.each do |param, opt| - if resource[param] - optional_opts.push(opt).push(resource[param]) - end - end - - auth_nova('network-create', - resource[:label], - '--fixed-range-v4', - resource[:name], - optional_opts - ) - end - - def exists? - begin - network_list = nova_manage("network", "list") - return network_list.split("\n")[1..-1].detect do |n| - # TODO - this does not take the CIDR into accont. Does it matter? - n =~ /^(\S+)\s+(#{resource[:network].split('/').first})/ - end - rescue - return false - end - end - - - def destroy - nova_manage("network", "delete", resource[:network]) - end - -end diff --git a/spec/unit/provider/nova_network/nova_spec.rb b/spec/unit/provider/nova_network/nova_spec.rb new file mode 100644 index 000000000..091a0982c --- /dev/null +++ b/spec/unit/provider/nova_network/nova_spec.rb @@ -0,0 +1,63 @@ +require 'puppet' +require 'puppet/provider/nova_network/nova' +require 'tempfile' + +provider_class = Puppet::Type.type(:nova_network).provider(:nova) + +describe provider_class do + + let :net_attrs do + { + :network => '10.20.0.0/16', + :label => 'novanetwork', + :ensure => 'present', + } + end + + let :resource do + Puppet::Type::Nova_network.new(net_attrs) + end + + let :provider do + provider_class.new(resource) + end + + shared_examples 'nova_network' do + describe '#exists?' do + it 'should check non-existsing network' do + provider.expects(:auth_nova).with("network-list") + .returns('"+--------------------------------------+-------------+-------------+\n| ID | Label | Cidr |\n+--------------------------------------+-------------+-------------+\n| 703edc62-36ab-4c41-9d73-884b30e9acbd | novanetwork | 10.0.0.0/16 |\n+--------------------------------------+-------------+-------------+\n" +') + expect(provider.exists?).to be_falsey + end + + it 'should check existsing network' do + provider.expects(:auth_nova).with("network-list") + .returns('"+--------------------------------------+-------------+-------------+\n| ID | Label | Cidr |\n+--------------------------------------+-------------+-------------+\n| 703edc62-36ab-4c41-9d73-884b30e9acbd | novanetwork | 10.20.0.0/16 |\n+--------------------------------------+-------------+-------------+\n" +') + expect(provider.exists?).to be_truthy + end + end + + describe '#create' do + it 'should create network' do + provider.expects(:auth_nova).with("network-create", ['novanetwork', '--fixed-range-v4', '10.20.0.0/16'] ) + .returns('"+--------------------------------------+-------------+-------------+\n| ID | Label | Cidr |\n+--------------------------------------+-------------+-------------+\n| 703edc62-36ab-4c41-9d73-88sdfsdfsdfsd | nova-network | 10.20.0.0/16 |\n+--------------------------------------+-------------+-------------+\n" +') + provider.create + end + end + + describe '#destroy' do + it 'should destroy network' do + resource[:ensure] = :absent + provider.expects(:auth_nova).with("network-delete", "10.20.0.0/16") + .returns('"+--------------------------------------+-------------+-------------+\n| ID | Label | Cidr |\n+--------------------------------------+-------------+-------------+\n +') + provider.destroy + end + end + end + + it_behaves_like('nova_network') +end