f5bbbf06d396b136f3d4569aa691234f249b09c2
[snaps.git] / snaps / config / router.py
1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
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:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15 from snaps.config.network import PortConfig
16 from snaps.openstack.utils import neutron_utils, keystone_utils
17
18
19 class RouterConfig(object):
20     """
21     Class representing a router configuration
22     """
23
24     def __init__(self, **kwargs):
25         """
26         Constructor - all parameters are optional
27         :param name: The router name.
28         :param project_name: The name of the project who owns the network. Only
29                              administrative users can specify a project ID
30                              other than their own. You cannot change this value
31                              through authorization policies.
32         :param external_gateway: Name of the external network to which to route
33         :param admin_state_up: The administrative status of the router.
34                                True = up / False = down (default True)
35         :param internal_subnets: List of subnet names to which to connect this
36                                  router for Floating IP purposes
37         :param port_settings: List of PortConfig objects
38         :return:
39         """
40         self.name = kwargs.get('name')
41         self.project_name = kwargs.get('project_name')
42         self.external_gateway = kwargs.get('external_gateway')
43
44         self.admin_state_up = kwargs.get('admin_state_up', True)
45         self.enable_snat = kwargs.get('enable_snat')
46         if kwargs.get('internal_subnets'):
47             self.internal_subnets = kwargs['internal_subnets']
48         else:
49             self.internal_subnets = list()
50
51         self.port_settings = list()
52         if kwargs.get('interfaces', kwargs.get('port_settings')):
53             interfaces = kwargs.get('interfaces', kwargs.get('port_settings'))
54             for interface in interfaces:
55                 if isinstance(interface, PortConfig):
56                     self.port_settings.append(interface)
57                 else:
58                     self.port_settings.append(
59                         PortConfig(**interface['port']))
60
61         if not self.name:
62             raise RouterConfigError('Name is required')
63
64     def dict_for_neutron(self, neutron, os_creds):
65         """
66         Returns a dictionary object representing this object.
67         This is meant to be converted into JSON designed for use by the Neutron
68         API
69
70         TODO - expand automated testing to exercise all parameters
71         :param neutron: The neutron client to retrieve external network
72                         information if necessary
73         :param os_creds: The OpenStack credentials for retrieving the keystone
74                          client for looking up the project ID when the
75                          self.project_name is not None
76         :return: the dictionary object
77         """
78         out = dict()
79         ext_gw = dict()
80
81         keystone = keystone_utils.keystone_client(os_creds)
82
83         if self.name:
84             out['name'] = self.name
85         if self.project_name:
86             project = keystone_utils.get_project(
87                 keystone=keystone, project_name=self.project_name)
88             if project:
89                     out['tenant_id'] = project.id
90             else:
91                 raise RouterConfigError(
92                     'Could not find project ID for project named - ' +
93                     self.project_name)
94         if self.admin_state_up is not None:
95             out['admin_state_up'] = self.admin_state_up
96         if self.external_gateway:
97             ext_net = neutron_utils.get_network(
98                 neutron, keystone, network_name=self.external_gateway)
99             if ext_net:
100                 ext_gw['network_id'] = ext_net.id
101                 out['external_gateway_info'] = ext_gw
102             else:
103                 raise RouterConfigError(
104                     'Could not find the external network named - ' +
105                     self.external_gateway)
106
107         return {'router': out}
108
109
110 class RouterConfigError(Exception):
111     """
112     Exception to be thrown when router settings attributes are incorrect
113     """