Add ability to manage binding for neutron port

It adds the possibility to add a binding host id
and a binding profile to a port

Change-Id: Idc145bce6c1072b0044b927b9327a0dd280ee2d7
This commit is contained in:
Alex Ruiz Estradera 2016-07-20 18:55:47 +02:00
parent 6556a9baae
commit a3dfb0e82c
4 changed files with 116 additions and 23 deletions

View File

@ -21,17 +21,19 @@ Puppet::Type.type(:neutron_port).provide(
attrs = get_neutron_resource_attrs("port", id)
attrs["name"] = attrs["id"] if attrs["name"].empty?
new(
:ensure => :present,
:name => attrs["name"],
:id => attrs["id"],
:status => attrs["status"],
:tenant_id => attrs["tenant_id"],
:network_id => attrs["network_id"],
:admin_state_up => attrs["admin_state_up"],
:network_name => get_network_name(attrs["network_id"]),
:subnet_name => get_subnet_name(parse_subnet_id(attrs["fixed_ips"])),
:subnet_id => parse_subnet_id(attrs["fixed_ips"]),
:ip_address => parse_ip_address(attrs["fixed_ips"])
:ensure => :present,
:name => attrs["name"],
:id => attrs["id"],
:status => attrs["status"],
:tenant_id => attrs["tenant_id"],
:network_id => attrs["network_id"],
:admin_state_up => attrs["admin_state_up"],
:network_name => get_network_name(attrs["network_id"]),
:subnet_name => get_subnet_name(parse_subnet_id(attrs["fixed_ips"])),
:subnet_id => parse_subnet_id(attrs["fixed_ips"]),
:ip_address => parse_ip_address(attrs["fixed_ips"]),
:binding_profile => parse_binding_profile_interface_name(attrs["binding:profile"]),
:binding_host_id => attrs["binding:host_id"],
)
end
end
@ -80,6 +82,15 @@ Puppet::Type.type(:neutron_port).provide(
opts << "--tenant_id=#{@resource[:tenant_id]}"
end
if @resource[:binding_host_id]
opts << "--binding:host_id=#{@resource[:binding_host_id]}"
end
if @resource[:binding_profile]
binding_profile_opts = @resource[:binding_profile].map{|k,v| "#{k}=#{v}"}.join(' ')
opts << "--binding:profile type=dict #{binding_profile_opts}"
end
results = auth_neutron(
"port-create",
"--format=shell",
@ -90,17 +101,19 @@ Puppet::Type.type(:neutron_port).provide(
attrs = self.class.parse_creation_output(results)
@property_hash = {
:ensure => :present,
:name => resource[:name],
:id => attrs["id"],
:status => attrs["status"],
:tenant_id => attrs["tenant_id"],
:network_id => attrs["network_id"],
:admin_state_up => attrs["admin_state_up"],
:network_name => resource[:network_name],
:subnet_name => resource[:subnet_name],
:subnet_id => self.class.parse_subnet_id(attrs["fixed_ips"]),
:ip_address => self.class.parse_ip_address(attrs["fixed_ips"])
:ensure => :present,
:name => resource[:name],
:id => attrs["id"],
:status => attrs["status"],
:tenant_id => attrs["tenant_id"],
:network_id => attrs["network_id"],
:admin_state_up => attrs["admin_state_up"],
:network_name => resource[:network_name],
:subnet_name => resource[:subnet_name],
:subnet_id => self.class.parse_subnet_id(attrs["fixed_ips"]),
:ip_address => self.class.parse_ip_address(attrs["fixed_ips"]),
:binding_profile => self.class.parse_binding_profile_interface_name(attrs["binding:profile"]),
:binding_host_id => attrs["binding:host_id"],
}
end
@ -184,4 +197,13 @@ Puppet::Type.type(:neutron_port).provide(
end
end
def self.parse_binding_profile_interface_name(binding_profile_)
match_data = /\{"interface_name": "(.*)"\}/.match(binding_profile_)
if match_data
match_data[1]
else
nil
end
end
end

View File

@ -74,6 +74,20 @@ Puppet::Type.newtype(:neutron_port) do
desc 'A uuid identifying the tenant which will own the port.'
end
newproperty(:binding_host_id) do
desc 'A uuid identifying the host where we will bind the port.'
end
newproperty(:binding_profile) do
desc 'A dictionary the enables the application running on the host
to pass and receive VIF port-specific information to the plug-in.'
validate do |value|
unless value.class == Hash
raise ArgumentError, "Binding profile is not a valid dictionary"
end
end
end
autorequire(:service) do
['neutron-server']
end

View File

@ -0,0 +1,5 @@
---
features:
- Add 'binding_host_id' and 'binding_profile'
support to neutron_port custom type.

View File

@ -16,7 +16,7 @@ describe provider_class do
:ensure => 'present',
:admin_state_up => 'True',
:tenant_id => '60f9544eb94c42a6b7e8e98c2be981b1',
:network_name => 'net1'
:network_name => 'net1',
}
end
@ -54,4 +54,56 @@ tenant_id="60f9544eb94c42a6b7e8e98c2be981b1"'
provider.create
end
end
describe 'when creating a port with binding profile and host_id' do
let :port_attrs do
{
:name => port_name,
:ensure => 'present',
:admin_state_up => 'True',
:tenant_id => '60f9544eb94c42a6b7e8e98c2be981b1',
:network_name => 'net1',
:binding_host_id => 'edge1',
:binding_profile => { 'interface_name' => 'eth1' },
}
end
let :resource do
Puppet::Type::Neutron_port.new(port_attrs)
end
it 'should call port-create with appropriate command line options' do
provider.class.stubs(:get_tenant_id).returns(port_attrs[:tenant_id])
provider.class.stubs(:get_binding_host_id).returns(port_attrs[:binding_host_id])
provider.class.stubs(:get_binding_profile).returns(port_attrs[:binding_profile])
output = 'Created a new port:
admin_state_up="True"
device_id=""
device_owner=""
fixed_ips="{\"subnet_id\": \"40af01ac-52c7-4235-bbcf-d9c02325ab5e\", \"ip_address\": \"192.168.0.39\"}"
id="5222573b-314d-45f9-b6bd-299288ba667a"
mac_address="fa:16:3e:45:3c:10"
name="port1"
network_id="98873773-aa34-4b87-af05-70903659246f"
security_groups="f1f0c3a3-9f2c-46b9-b2a5-b97d9a87bd7e"
status="ACTIVE"
tenant_id="60f9544eb94c42a6b7e8e98c2be981b1"
binding_host_id="edge1"
binding_profile="{\"interface_name\": \"eth1\"}"'
provider.expects(:auth_neutron).with('port-create',
'--format=shell', "--name=#{port_attrs[:name]}",
["--tenant_id=#{port_attrs[:tenant_id]}",
"--binding:host_id=#{port_attrs[:binding_host_id]}",
"--binding:profile type=dict interface_name=#{port_attrs[:binding_profile]['interface_name']}",
],
port_attrs[:network_name]).returns(output)
provider.create
end
end
end