From 3e3ffdfdd72c6d01417fffd5676175fe094afa3c Mon Sep 17 00:00:00 2001 From: Wenxin Wang Date: Sat, 2 Jan 2016 23:08:46 +0800 Subject: [PATCH] add ipv6 options to neutron_subnet type Allows setting the ipv6_ra_mode and ipv6_address_mode options to be when an ipv6 subnet is created. Change-Id: Ie7e6b489f5646ab469594f0ffea859f72b20fd89 --- lib/puppet/provider/neutron_subnet/neutron.rb | 14 +++++ lib/puppet/type/neutron_subnet.rb | 16 +++++ .../provider/neutron_subnet/neutron_spec.rb | 63 ++++++++++++++++++- spec/unit/type/neutron_subnet.rb | 25 ++++++++ 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 spec/unit/type/neutron_subnet.rb diff --git a/lib/puppet/provider/neutron_subnet/neutron.rb b/lib/puppet/provider/neutron_subnet/neutron.rb index 24688b124..5b695cad0 100644 --- a/lib/puppet/provider/neutron_subnet/neutron.rb +++ b/lib/puppet/provider/neutron_subnet/neutron.rb @@ -29,6 +29,8 @@ Puppet::Type.type(:neutron_subnet).provide( :id => attrs['id'], :cidr => attrs['cidr'], :ip_version => attrs['ip_version'], + :ipv6_ra_mode => attrs['ipv6_ra_mode'], + :ipv6_address_mode => attrs['ipv6_address_mode'], :gateway_ip => parse_gateway_ip(attrs['gateway_ip']), :allocation_pools => parse_allocation_pool(attrs['allocation_pools']), :host_routes => parse_host_routes(attrs['host_routes']), @@ -94,6 +96,14 @@ Puppet::Type.type(:neutron_subnet).provide( opts << "--ip-version=#{@resource[:ip_version]}" end + if @resource[:ipv6_ra_mode] + opts << "--ipv6-ra-mode=#{@resource[:ipv6_ra_mode]}" + end + + if @resource[:ipv6_address_mode] + opts << "--ipv6-address-mode=#{@resource[:ipv6_address_mode]}" + end + if @resource[:gateway_ip] if @resource[:gateway_ip] == '' opts << '--no-gateway' @@ -151,6 +161,8 @@ Puppet::Type.type(:neutron_subnet).provide( :id => attrs['id'], :cidr => attrs['cidr'], :ip_version => attrs['ip_version'], + :ipv6_ra_mode => attrs['ipv6_ra_mode'], + :ipv6_address_mode => attrs['ipv6_address_mode'], :gateway_ip => self.class.parse_gateway_ip(attrs['gateway_ip']), :allocation_pools => self.class.parse_allocation_pool(attrs['allocation_pools']), :host_routes => self.class.parse_host_routes(attrs['host_routes']), @@ -208,6 +220,8 @@ Puppet::Type.type(:neutron_subnet).provide( [ :cidr, :ip_version, + :ipv6_ra_mode, + :ipv6_address_mode, :network_id, :allocation_pools, :tenant_id, diff --git a/lib/puppet/type/neutron_subnet.rb b/lib/puppet/type/neutron_subnet.rb index 5fc9dcd2a..cef880a01 100644 --- a/lib/puppet/type/neutron_subnet.rb +++ b/lib/puppet/type/neutron_subnet.rb @@ -23,6 +23,16 @@ Puppet::Type.newtype(:neutron_subnet) do newvalues('4', '6') end + newproperty(:ipv6_ra_mode) do + desc 'The IPv6 RA (Router Advertisement) mode' + newvalues('dhcpv6-stateful', 'dhcpv6-stateless', 'slaac') + end + + newproperty(:ipv6_address_mode) do + desc 'The IPv6 Address mode' + newvalues('dhcpv6-stateful', 'dhcpv6-stateless', 'slaac') + end + newproperty(:allocation_pools, :array_matching => :all) do desc <<-EOT Array of Sub-ranges of cidr available for dynamic allocation to ports. @@ -112,6 +122,12 @@ Please provide a value for only one of tenant_name and tenant_id. EOT ) end + if (self[:ipv6_ra_mode] || self[:ipv6_address_mode]) && String(self[:ip_version]) != '6' + raise(Puppet::Error, <<-EOT +ipv6_ra_mode and ipv6_address_mode can only be used with ip_version set to '6' +EOT + ) + end end end diff --git a/spec/unit/provider/neutron_subnet/neutron_spec.rb b/spec/unit/provider/neutron_subnet/neutron_spec.rb index 0b3f473a2..52920e4b5 100644 --- a/spec/unit/provider/neutron_subnet/neutron_spec.rb +++ b/spec/unit/provider/neutron_subnet/neutron_spec.rb @@ -10,6 +10,10 @@ describe provider_class do 'net1' end + let :subnet_v6_name do + 'net2' + end + let :subnet_attrs do { :name => subnet_name, @@ -26,6 +30,22 @@ describe provider_class do } end + let :subnet_v6_attrs do + { + :name => subnet_v6_name, + :ensure => 'present', + :cidr => '2001:abcd::/64', + :ip_version => '6', + :gateway_ip => '2001:abcd::1', + :enable_dhcp => 'False', + :network_name => 'net2', + :tenant_id => '60f9544eb94c42a6b7e8e98c2be981b1', + :allocation_pools => 'start=2001:abcd::2,end=2001:abcd::ffff:ffff:ffff:fffe', + :dns_nameservers => '2001:4860:4860::8888', + :host_routes => 'destination=2001:abcd:0:1::/64,nexthop=2001:abcd::1', + } + end + let :resource do Puppet::Type::Neutron_subnet.new(subnet_attrs) end @@ -35,7 +55,6 @@ describe provider_class do end describe 'when creating a subnet' do - it 'should call subnet-create with appropriate command line options' do provider.class.stubs(:get_tenant_id).returns(subnet_attrs[:tenant_id]) @@ -68,6 +87,48 @@ tenant_id="60f9544eb94c42a6b7e8e98c2be981b1"' end end + describe 'when creating a ipv6 subnet' do + + let :resource do + Puppet::Type::Neutron_subnet.new(subnet_v6_attrs) + end + + let :provider do + provider_class.new(resource) + end + + it 'should call subnet-create with appropriate command line options' do + provider.class.stubs(:get_tenant_id).returns(subnet_v6_attrs[:tenant_id]) + + output = 'Created a new subnet: +allocation_pools="{\"start\": \"2001:abcd::2\", \"end\": \"2001:abcd::ffff:ffff:ffff:fffe\"}" +cidr="2001:abcd::/64" +dns_nameservers="2001:4860:4860::8888" +enable_dhcp="False" +gateway_ip="2001:abcd::1" +host_routes="{\"nexthop\": \"2001:abcd::1\", \"destination\": \"2001:abcd:0:1::/64\"}" +id="dd5e0ef1-2c88-4b0b-ba08-7df65be87963" +ip_version="6" +name="net1" +network_id="98873773-aa34-4b87-af05-70903659246f" +tenant_id="60f9544eb94c42a6b7e8e98c2be981b1"' + + provider.expects(:auth_neutron).with('subnet-create', '--format=shell', + ["--name=#{subnet_v6_attrs[:name]}", + "--ip-version=#{subnet_v6_attrs[:ip_version]}", + "--gateway-ip=#{subnet_v6_attrs[:gateway_ip]}", + "--disable-dhcp", + "--allocation-pool=#{subnet_v6_attrs[:allocation_pools]}", + "--dns-nameserver=#{subnet_v6_attrs[:dns_nameservers]}", + "--host-route=#{subnet_v6_attrs[:host_routes]}", + "--tenant_id=#{subnet_v6_attrs[:tenant_id]}", + subnet_v6_name], + subnet_v6_attrs[:cidr]).returns(output) + + provider.create + end + end + describe 'when updating a subnet' do it 'should call subnet-update to change gateway_ip' do provider.expects(:auth_neutron).with('subnet-update', diff --git a/spec/unit/type/neutron_subnet.rb b/spec/unit/type/neutron_subnet.rb new file mode 100644 index 000000000..d3e5718bd --- /dev/null +++ b/spec/unit/type/neutron_subnet.rb @@ -0,0 +1,25 @@ +require 'puppet' +require 'puppet/type/neutron_subnet' + +describe 'Puppet::Type.type(:neutron_subnet)' do + it 'should not allow ipv6 settings with ip_version = 4' do + expect{Puppet::Type.type(:neutron_subnet).new( + :name => 'subnet', + :network_name => 'net', + :cidr => '2001:abcd::/64', + :ip_version => '4', + :ipv6_ra_mode => 'slaac' + )}.to raise_error(Puppet::ResourceError) + end + + it 'should allow ipv6 settings with ip_version = 6' do + expect{Puppet::Type.type(:neutron_subnet).new( + :name => 'subnet', + :network_name => 'net', + :cidr => '2001:abcd::/64', + :ip_version => '6', + :ipv6_ra_mode => 'slaac' + )}.not_to raise_error + end + +end