1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
# and others. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from snaps.config.network import PortConfig
from snaps.openstack.utils import neutron_utils, keystone_utils
class RouterConfig(object):
"""
Class representing a router configuration
"""
def __init__(self, **kwargs):
"""
Constructor - all parameters are optional
:param name: The router name.
:param project_name: The name of the project who owns the network. Only
administrative users can specify a project ID
other than their own. You cannot change this value
through authorization policies.
:param external_gateway: Name of the external network to which to route
:param admin_state_up: The administrative status of the router.
True = up / False = down (default True)
:param internal_subnets: List of subnet names to which to connect this
router (this way is deprecated).
*** NEW WAY ***
List of dict where the key is 'subnet' that
contains members with the following keys:
project_name, network_name, and subnet_name
:param port_settings: List of PortConfig objects
:return:
"""
self.name = kwargs.get('name')
self.project_name = kwargs.get('project_name')
self.external_gateway = kwargs.get('external_gateway')
self.admin_state_up = kwargs.get('admin_state_up', True)
self.enable_snat = kwargs.get('enable_snat')
if kwargs.get('internal_subnets'):
self.internal_subnets = kwargs['internal_subnets']
if isinstance(self.internal_subnets, dict):
if 'subnet' not in self.internal_subnets:
raise RouterConfigError(
'subnet is a required key to internal_subnets')
if 'project_name' not in self.internal_subnets['subnet']:
raise RouterConfigError(
'subnet.project is a required key to subnet')
if 'network_name' not in self.internal_subnets['subnet']:
raise RouterConfigError(
'network_name is a required key to subnet')
if 'subnet_name' not in self.internal_subnets['subnet']:
raise RouterConfigError(
'subnet_name is a required key to subnet')
else:
self.internal_subnets = list()
self.port_settings = list()
if kwargs.get('interfaces', kwargs.get('port_settings')):
interfaces = kwargs.get('interfaces', kwargs.get('port_settings'))
for interface in interfaces:
if isinstance(interface, PortConfig):
self.port_settings.append(interface)
else:
self.port_settings.append(
PortConfig(**interface['port']))
if not self.name:
raise RouterConfigError('Name is required')
def dict_for_neutron(self, neutron, os_creds):
"""
Returns a dictionary object representing this object.
This is meant to be converted into JSON designed for use by the Neutron
API
TODO - expand automated testing to exercise all parameters
:param neutron: The neutron client to retrieve external network
information if necessary
:param os_creds: The OpenStack credentials for retrieving the keystone
client for looking up the project ID when the
self.project_name is not None
:return: the dictionary object
"""
out = dict()
ext_gw = dict()
session = keystone_utils.keystone_session(os_creds)
keystone = keystone_utils.keystone_client(os_creds, session)
try:
if self.name:
out['name'] = self.name
if self.project_name:
project = keystone_utils.get_project(
keystone=keystone, project_name=self.project_name)
if project:
out['tenant_id'] = project.id
else:
raise RouterConfigError(
'Could not find project ID for project named - ' +
self.project_name)
if self.admin_state_up is not None:
out['admin_state_up'] = self.admin_state_up
if self.external_gateway:
ext_net = neutron_utils.get_network(
neutron, keystone, network_name=self.external_gateway)
if ext_net:
ext_gw['network_id'] = ext_net.id
out['external_gateway_info'] = ext_gw
else:
raise RouterConfigError(
'Could not find the external network named - ' +
self.external_gateway)
finally:
keystone_utils.close_session(session)
return {'router': out}
class RouterConfigError(Exception):
"""
Exception to be thrown when router settings attributes are incorrect
"""
|