1 require File.join(File.dirname(__FILE__), "..","..","..",
2 "puppet/provider/neutron")
4 Puppet::Type.type(:neutron_port).provide(
6 :parent => Puppet::Provider::Neutron
9 Neutron provider to manage neutron_port type.
11 Assumes that the neutron service is configured on the same host.
13 #TODO No security group support
15 commands :neutron => "neutron"
20 list_neutron_resources("port").collect do |id|
21 attrs = get_neutron_resource_attrs("port", id)
22 attrs["name"] = attrs["id"] if attrs["name"].empty?
25 :name => attrs["name"],
27 :status => attrs["status"],
28 :tenant_id => attrs["tenant_id"],
29 :network_id => attrs["network_id"],
30 :admin_state_up => attrs["admin_state_up"],
31 :network_name => get_network_name(attrs["network_id"]),
32 :subnet_name => get_subnet_name(parse_subnet_id(attrs["fixed_ips"])),
33 :subnet_id => parse_subnet_id(attrs["fixed_ips"]),
34 :ip_address => parse_ip_address(attrs["fixed_ips"])
39 def self.prefetch(resources)
40 instances_ = instances
41 resources.keys.each do |name|
42 if provider = instances_.find{ |instance| instance.name == name }
43 resources[name].provider = provider
49 @property_hash[:ensure] == :present
55 if @resource[:admin_state_up] == "False"
56 opts << "--admin-state-down"
59 if @resource[:ip_address]
60 # The spec says that multiple ip addresses may be specified, but this
61 # doesn't seem to work yet.
63 opts << @resource[:ip_address].map{|ip|"ip_address=#{ip}"}.join(',')
66 if @resource[:subnet_name]
67 # The spec says that multiple subnets may be specified, but this doesn't
70 opts << @resource[:subnet_name].map{|s|"subnet_id=#{s}"}.join(',')
73 if @resource[:tenant_name]
74 tenant_id = self.class.get_tenant_id(
76 @resource[:tenant_name]
78 opts << "--tenant_id=#{tenant_id}"
79 elsif @resource[:tenant_id]
80 opts << "--tenant_id=#{@resource[:tenant_id]}"
83 results = auth_neutron(
86 "--name=#{resource[:name]}",
88 resource[:network_name]
91 if results =~ /Created a new port:/
92 attrs = self.class.parse_creation_output(results)
95 :name => resource[:name],
97 :status => attrs["status"],
98 :tenant_id => attrs["tenant_id"],
99 :network_id => attrs["network_id"],
100 :admin_state_up => attrs["admin_state_up"],
101 :network_name => resource[:network_name],
102 :subnet_name => resource[:subnet_name],
103 :subnet_id => self.class.parse_subnet_id(attrs["fixed_ips"]),
104 :ip_address => self.class.parse_ip_address(attrs["fixed_ips"])
107 fail("did not get expected message on port creation, got #{results}")
112 auth_neutron("port-delete", name)
113 @property_hash[:ensure] = :absent
116 def admin_state_up=(value)
117 auth_neutron("port-update", "--admin-state-up=#{value}", name)
122 def self.get_network_name(network_id_)
124 network_instances = Puppet::Type.type("neutron_network").instances
125 network_name = network_instances.find do |instance|
126 instance.provider.id == network_id_
132 def get_network_name(network_id_)
133 @get_network_name ||= self.class.get_network_name(network_id_)
136 def self.get_subnet_name(subnet_id_)
138 subnet_ids = Array(subnet_id_)
139 subnet_instances = Puppet::Type.type("neutron_subnet").instances
140 subnet_names = subnet_instances.collect do |instance|
141 if subnet_ids.include?(instance.provider.id)
142 instance.provider.name
147 if subnet_names.length > 1
155 def get_subnet_name(subnet_id_)
156 @subnet_name ||= self.class.subnet_name(subnet_id_)
159 def self.parse_subnet_id(fixed_ips_)
160 subnet_ids = Array(fixed_ips_).collect do |json|
161 match_data = /\{"subnet_id": "(.*)", /.match(json)
168 if subnet_ids.length > 1
175 def self.parse_ip_address(fixed_ips_)
176 ip_addresses = Array(fixed_ips_).collect do |json|
177 match_data = /"ip_address": "(.*)"\}/.match(json)
184 if ip_addresses.length > 1