From deaaa35b63a00eeb4a3f5db47cb02e509f8bc6c5 Mon Sep 17 00:00:00 2001 From: Javier Pena Date: Thu, 26 Jan 2017 17:44:57 +0100 Subject: [PATCH] Fix neutron_subnet provider for neutronclient 6.1.0 python-neutronclient 6.1.0 has changed the output format for some fields [1], breaking the neutron_subnet provider. This patch adds support for the new output, while keeping backwards compatibility. [1] Old output: allocation_pools="{\"start\": \"172.24.4.2\", \"end\": \"172.24.4.254\"}" New output: allocation_pools="[{u'start': u'172.24.4.2', u'end': u'172.24.4.254'}]" Change-Id: Iad1bd41541a46b306d01f3343710080e3e93d8df --- lib/puppet/provider/neutron_subnet/neutron.rb | 20 ++++++++--- .../provider/neutron_subnet/neutron_spec.rb | 33 +++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/lib/puppet/provider/neutron_subnet/neutron.rb b/lib/puppet/provider/neutron_subnet/neutron.rb index b2daad801..9f883fb29 100644 --- a/lib/puppet/provider/neutron_subnet/neutron.rb +++ b/lib/puppet/provider/neutron_subnet/neutron.rb @@ -67,9 +67,11 @@ Puppet::Type.type(:neutron_subnet).provide( def self.parse_allocation_pool(values) allocation_pools = [] - return [] if values.empty? + return [] if values.empty? or values == '[]' for value in Array(values) - allocation_pool = JSON.parse(value.gsub(/\\"/,'"')) + allocation_pool = JSON.parse(value.gsub(/\\"/,'"').gsub('u\'', '"') + .gsub('\'','"').gsub('[', '') + .gsub(']', '')) start_ip = allocation_pool['start'] end_ip = allocation_pool['end'] allocation_pools << "start=#{start_ip},end=#{end_ip}" @@ -79,17 +81,25 @@ Puppet::Type.type(:neutron_subnet).provide( def self.parse_host_routes(values) host_routes = [] - return [] if values.empty? + return [] if values.empty? or values == '[]' + # Strip brackets from output, needed after neutronclient >= 6.1.0 + values = values.gsub('[', '').gsub(']', '') for value in Array(values) - host_route = JSON.parse(value.gsub(/\\"/,'"')) + host_route = JSON.parse(value.gsub(/\\"/,'"').gsub('u\'', '"') + .gsub('\'','"')) nexthop = host_route['nexthop'] destination = host_route['destination'] - host_routes << "nexthop=#{nexthop},destination=#{destination}" + host_routes << "destination=#{destination},nexthop=#{nexthop}" end return host_routes end def self.parse_dns_nameservers(values) + # With neutronclient >= 6.1.0 we need to parse the string a bit + if values.is_a? String + values = values.gsub('u\'', '').gsub('\'','').gsub('[', '') + .gsub(']', '').gsub(',', '').split(' ') + end # just enforce that this is actually an array return Array(values) end diff --git a/spec/unit/provider/neutron_subnet/neutron_spec.rb b/spec/unit/provider/neutron_subnet/neutron_spec.rb index 52920e4b5..6d83cbbcd 100644 --- a/spec/unit/provider/neutron_subnet/neutron_spec.rb +++ b/spec/unit/provider/neutron_subnet/neutron_spec.rb @@ -87,6 +87,39 @@ tenant_id="60f9544eb94c42a6b7e8e98c2be981b1"' end end + describe 'when creating a subnet with neutronclient >= 6.1.0' do + it 'should call subnet-create with appropriate command line options' do + provider.class.stubs(:get_tenant_id).returns(subnet_attrs[:tenant_id]) + + output = 'Created a new subnet: +allocation_pools="[{u\'start\': u\'10.0.0.2\', u\'end\': u\'10.0.0.10\'}]" +cidr="10.0.0.0/24" +dns_nameservers="[u\'8.8.8.8\']" +enable_dhcp="False" +gateway_ip="10.0.0.1" +host_routes="[{u\'destination\': u\'12.0.0.0/24\', u\'nexthop\': u\'10.0.0.1\'}]" +id="dd5e0ef1-2c88-4b0b-ba08-7df65be87963" +ip_version="4" +name="net1" +network_id="98873773-aa34-4b87-af05-70903659246f" +tenant_id="60f9544eb94c42a6b7e8e98c2be981b1"' + + provider.expects(:auth_neutron).with('subnet-create', '--format=shell', + ["--name=#{subnet_attrs[:name]}", + "--ip-version=#{subnet_attrs[:ip_version]}", + "--gateway-ip=#{subnet_attrs[:gateway_ip]}", + "--disable-dhcp", + "--allocation-pool=#{subnet_attrs[:allocation_pools]}", + "--dns-nameserver=#{subnet_attrs[:dns_nameservers]}", + "--host-route=#{subnet_attrs[:host_routes]}", + "--tenant_id=#{subnet_attrs[:tenant_id]}", + subnet_name], + subnet_attrs[:cidr]).returns(output) + + provider.create + end + end + describe 'when creating a ipv6 subnet' do let :resource do