try again, with puppetforge modules, correctly included now
[mirror/dsa-puppet.git] / 3rdparty / modules / neutron / lib / puppet / provider / neutron_port / neutron.rb
1 require File.join(File.dirname(__FILE__), "..","..","..",
2                   "puppet/provider/neutron")
3
4 Puppet::Type.type(:neutron_port).provide(
5   :neutron,
6   :parent => Puppet::Provider::Neutron
7 ) do
8   desc <<-EOT
9     Neutron provider to manage neutron_port type.
10
11     Assumes that the neutron service is configured on the same host.
12   EOT
13   #TODO No security group support
14
15   commands :neutron => "neutron"
16
17   mk_resource_methods
18
19   def self.instances
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?
23       new(
24         :ensure         => :present,
25         :name           => attrs["name"],
26         :id             => attrs["id"],
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"])
35       )
36     end
37   end
38
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
44       end
45     end
46   end
47
48   def exists?
49     @property_hash[:ensure] == :present
50   end
51
52   def create
53     opts = Array.new
54
55     if @resource[:admin_state_up] == "False"
56       opts << "--admin-state-down"
57     end
58
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.
62       opts << "--fixed-ip"
63       opts << @resource[:ip_address].map{|ip|"ip_address=#{ip}"}.join(',')
64     end
65
66     if @resource[:subnet_name]
67       # The spec says that multiple subnets may be specified, but this doesn't
68       # seem to work yet.
69       opts << "--fixed-ip"
70       opts << @resource[:subnet_name].map{|s|"subnet_id=#{s}"}.join(',')
71     end
72
73     if @resource[:tenant_name]
74       tenant_id = self.class.get_tenant_id(
75         model.catalog,
76         @resource[:tenant_name]
77       )
78       opts << "--tenant_id=#{tenant_id}"
79     elsif @resource[:tenant_id]
80       opts << "--tenant_id=#{@resource[:tenant_id]}"
81     end
82
83     results = auth_neutron(
84       "port-create",
85       "--format=shell",
86       "--name=#{resource[:name]}",
87       opts,
88       resource[:network_name]
89     )
90
91     if results =~ /Created a new port:/
92       attrs = self.class.parse_creation_output(results)
93       @property_hash = {
94         :ensure         => :present,
95         :name           => resource[:name],
96         :id             => attrs["id"],
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"])
105       }
106     else
107       fail("did not get expected message on port creation, got #{results}")
108     end
109   end
110
111   def destroy
112     auth_neutron("port-delete", name)
113     @property_hash[:ensure] = :absent
114   end
115
116   def admin_state_up=(value)
117     auth_neutron("port-update", "--admin-state-up=#{value}", name)
118   end
119
120   private
121
122   def self.get_network_name(network_id_)
123     if 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_
127       end.provider.name
128     end
129     network_name
130   end
131
132   def get_network_name(network_id_)
133     @get_network_name ||= self.class.get_network_name(network_id_)
134   end
135
136   def self.get_subnet_name(subnet_id_)
137     if 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
143         else
144           nil
145         end
146       end.compact
147       if subnet_names.length > 1
148         subnet_names
149       else
150         subnet_names.first
151       end
152     end
153   end
154
155   def get_subnet_name(subnet_id_)
156     @subnet_name ||= self.class.subnet_name(subnet_id_)
157   end
158
159   def self.parse_subnet_id(fixed_ips_)
160     subnet_ids = Array(fixed_ips_).collect do |json|
161       match_data = /\{"subnet_id": "(.*)", /.match(json)
162       if match_data
163         match_data[1]
164       else
165         nil
166       end
167     end.compact
168     if subnet_ids.length > 1
169       subnet_ids
170     else
171       subnet_ids.first
172     end
173   end
174
175   def self.parse_ip_address(fixed_ips_)
176     ip_addresses = Array(fixed_ips_).collect do |json|
177       match_data = /"ip_address": "(.*)"\}/.match(json)
178       if match_data
179         match_data[1]
180       else
181         nil
182       end
183     end.compact
184     if ip_addresses.length > 1
185       ip_addresses
186     else
187       ip_addresses.first
188     end
189   end
190
191 end