1 # vim: tabstop=4 shiftwidth=4 softtabstop=4 |
|
2 |
|
3 # Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. |
|
4 # |
|
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
6 # not use this file except in compliance with the License. You may obtain |
|
7 # a copy of the License at |
|
8 # |
|
9 # http://www.apache.org/licenses/LICENSE-2.0 |
|
10 # |
|
11 # Unless required by applicable law or agreed to in writing, software |
|
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
14 # License for the specific language governing permissions and limitations |
|
15 # under the License. |
|
16 # |
|
17 # @author: Girish Moodalbail, Oracle, Inc. |
|
18 |
|
19 import socket |
|
20 import uuid |
|
21 |
|
22 import netaddr |
|
23 |
|
24 from oslo.config import cfg |
|
25 from quantum.agent.common import config |
|
26 from quantum.agent.solaris import interface |
|
27 from quantum.openstack.common import importutils |
|
28 from quantum.openstack.common import log as logging |
|
29 |
|
30 LOG = logging.getLogger(__name__) |
|
31 |
|
32 |
|
33 class DeviceManager(object): |
|
34 OPTS = [ |
|
35 cfg.StrOpt('interface_driver', |
|
36 help=_('The driver used to manage the virtual interface.')) |
|
37 ] |
|
38 |
|
39 def __init__(self, conf, plugin): |
|
40 self.conf = conf |
|
41 self.root_helper = config.get_root_helper(conf) |
|
42 self.plugin = plugin |
|
43 cfg.CONF.register_opts(DeviceManager.OPTS) |
|
44 cfg.CONF.register_opts(interface.OPTS) |
|
45 if not conf.interface_driver: |
|
46 raise SystemExit(_('You must specify an interface driver.')) |
|
47 try: |
|
48 self.driver = importutils.import_object(conf.interface_driver, |
|
49 conf) |
|
50 except ImportError as ie: |
|
51 raise SystemExit(_('Error importing interface driver %s: %s') |
|
52 % (conf.interface_driver, ie)) |
|
53 |
|
54 def get_interface_name(self, network, port=None): |
|
55 """Return interface(device) name for use by the DHCP process.""" |
|
56 |
|
57 if not port: |
|
58 device_id = self.get_device_id(network) |
|
59 port = self.plugin.get_dhcp_port(network.id, device_id) |
|
60 return self.driver.get_device_name(port) |
|
61 |
|
62 def get_device_id(self, network): |
|
63 """Return a unique DHCP device ID for this host on the network.""" |
|
64 |
|
65 # There could be more than one dhcp server per network, so create |
|
66 # a device id that combines host and network ids |
|
67 host_uuid = uuid.uuid5(uuid.NAMESPACE_DNS, socket.gethostname()) |
|
68 return 'dhcp%s-%s' % (host_uuid, network.id) |
|
69 |
|
70 def setup(self, network, reuse_existing=False): |
|
71 """Create and initialize a device for network's DHCP on this host.""" |
|
72 device_id = self.get_device_id(network) |
|
73 port = self.plugin.get_dhcp_port(network.id, device_id) |
|
74 |
|
75 interface_name = self.get_interface_name(network, port) |
|
76 |
|
77 self.driver.plug(network.tenant_id, network.id, port.id, |
|
78 interface_name) |
|
79 ip_cidrs = [] |
|
80 for fixed_ip in port.fixed_ips: |
|
81 subnet = fixed_ip.subnet |
|
82 net = netaddr.IPNetwork(subnet.cidr) |
|
83 ip_cidr = '%s/%s' % (fixed_ip.ip_address, net.prefixlen) |
|
84 ip_cidrs.append(ip_cidr) |
|
85 |
|
86 self.driver.init_l3(interface_name, ip_cidrs) |
|
87 |
|
88 return interface_name |
|
89 |
|
90 def update(self, network): |
|
91 """Update device settings for the network's DHCP on this host.""" |
|
92 pass |
|
93 |
|
94 def destroy(self, network, device_name): |
|
95 """Destroy the device used for the network's DHCP on this host.""" |
|
96 |
|
97 self.driver.fini_l3(device_name) |
|
98 self.driver.unplug(device_name) |
|
99 self.plugin.release_dhcp_port(network.id, |
|
100 self.get_device_id(network)) |
|