1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 from neutronclient.common.exceptions import NotFound, Unauthorized
19 from snaps.config.router import RouterConfig
20 from snaps.openstack.openstack_creator import OpenStackNetworkObject
21 from snaps.openstack.utils import neutron_utils, keystone_utils
23 __author__ = 'spisarski'
25 logger = logging.getLogger('OpenStackNetwork')
28 class OpenStackRouter(OpenStackNetworkObject):
30 Class responsible for managing a router in OpenStack
33 def __init__(self, os_creds, router_settings):
35 Constructor - all parameters are required
36 :param os_creds: The credentials to connect with OpenStack
37 :param router_settings: The settings used to create a router object
38 (must be an instance of the RouterConfig
41 super(self.__class__, self).__init__(os_creds)
43 if not router_settings:
44 raise RouterCreationError('router_settings is required')
46 self.__keystone = None
48 self.router_settings = router_settings
50 # Attributes instantiated on create()
52 self.__internal_subnets = list()
53 self.__internal_router_interface = None
55 # Dict where the port object is the key and any newly created router
56 # interfaces are the value
61 Loads the existing router.
62 :return: the Router domain object
64 super(self.__class__, self).initialize()
66 self.__keystone = keystone_utils.keystone_client(self._os_creds)
69 self.__router = neutron_utils.get_router(
70 self._neutron, self.__keystone,
71 router_settings=self.router_settings,
72 project_name=self._os_creds.project_name)
73 except Unauthorized as e:
74 logger.warn('Unable to lookup router with name %s - %s',
75 self.router_settings.name, e)
78 for internal_subnet_name in self.router_settings.internal_subnets:
79 internal_subnet = neutron_utils.get_subnet(
80 self._neutron, subnet_name=internal_subnet_name)
82 self.__internal_subnets.append(internal_subnet)
84 raise RouterCreationError(
85 'Subnet not found with name ' + internal_subnet_name)
87 for port_setting in self.router_settings.port_settings:
88 port = neutron_utils.get_port(
89 self._neutron, self.__keystone, port_settings=port_setting,
90 project_name=self._os_creds.project_name)
92 self.__ports.append(port)
98 Responsible for creating the router.
99 :return: the Router domain object
103 if not self.__router:
104 self.__router = neutron_utils.create_router(
105 self._neutron, self._os_creds, self.router_settings)
107 for internal_subnet_name in self.router_settings.internal_subnets:
108 internal_subnet = neutron_utils.get_subnet(
109 self._neutron, subnet_name=internal_subnet_name)
111 self.__internal_subnets.append(internal_subnet)
113 logger.debug('Adding router to subnet...')
114 router_intf = neutron_utils.add_interface_router(
115 self._neutron, self.__router,
116 subnet=internal_subnet)
117 self.__internal_router_interface = router_intf
119 raise RouterCreationError(
120 'Subnet not found with name ' + internal_subnet_name)
122 for port_setting in self.router_settings.port_settings:
123 port = neutron_utils.get_port(
124 self._neutron, self.__keystone, port_settings=port_setting,
125 project_name=self._os_creds.project_name)
127 'Retrieved port %s for router - %s', port_setting.name,
128 self.router_settings.name)
130 self.__ports.append(port)
133 port = neutron_utils.create_port(
134 self._neutron, self._os_creds, port_setting)
137 'Created port %s for router - %s',
139 self.router_settings.name)
140 self.__ports.append(port)
141 neutron_utils.add_interface_router(
142 self._neutron, self.__router, port=port)
144 raise RouterCreationError(
145 'Error creating port with name - '
148 self.__router = neutron_utils.get_router_by_id(
149 self._neutron, self.__router.id)
154 Removes and deletes all items created in reverse order.
156 for port in self.__ports:
158 'Removing router interface from router %s and port %s',
159 self.router_settings.name, port.name)
161 neutron_utils.remove_interface_router(self._neutron,
162 self.__router, port=port)
165 self.__ports = list()
167 for internal_subnet in self.__internal_subnets:
169 'Removing router interface from router %s and subnet %s',
170 self.router_settings.name, internal_subnet.name)
172 neutron_utils.remove_interface_router(self._neutron,
174 subnet=internal_subnet)
177 self.__internal_subnets = list()
180 logger.info('Removing router ' + self.router_settings.name)
182 neutron_utils.delete_router(self._neutron, self.__router)
187 def get_router(self):
189 Returns the OpenStack router object
194 def get_internal_router_interface(self):
196 Returns the OpenStack internal router interface object
199 return self.__internal_router_interface
202 class RouterCreationError(Exception):
204 Exception to be thrown when an router instance cannot be created
208 class RouterSettings(RouterConfig):
210 Class to hold the configuration settings required for creating OpenStack
215 def __init__(self, **kwargs):
216 from warnings import warn
217 warn('Use snaps.config.router.RouterConfig instead',
219 super(self.__class__, self).__init__(**kwargs)