Fixes public vlan network settings
[apex.git] / lib / python / apex / network_environment.py
1 ##############################################################################
2 # Copyright (c) 2016 Tim Rozet (trozet@redhat.com) and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 import yaml
11 import re
12 from .common.constants import (
13     ADMIN_NETWORK,
14     PRIVATE_NETWORK,
15     STORAGE_NETWORK,
16     PUBLIC_NETWORK,
17     API_NETWORK,
18 )
19
20 PORTS = '/ports'
21 # Resources defined by <resource name>: <prefix>
22 EXTERNAL_RESOURCES = {'OS::TripleO::Network::External': None,
23                       'OS::TripleO::Network::Ports::ExternalVipPort': PORTS,
24                       'OS::TripleO::Controller::Ports::ExternalPort': PORTS,
25                       'OS::TripleO::Compute::Ports::ExternalPort': PORTS}
26 TENANT_RESOURCES = {'OS::TripleO::Network::Tenant': None,
27                     'OS::TripleO::Controller::Ports::TenantPort': PORTS,
28                     'OS::TripleO::Compute::Ports::TenantPort': PORTS}
29 STORAGE_RESOURCES = {'OS::TripleO::Network::Storage': None,
30                      'OS::TripleO::Network::Ports::StorageVipPort': PORTS,
31                      'OS::TripleO::Controller::Ports::StoragePort': PORTS,
32                      'OS::TripleO::Compute::Ports::StoragePort': PORTS}
33 API_RESOURCES = {'OS::TripleO::Network::InternalApi': None,
34                  'OS::TripleO::Network::Ports::InternalApiVipPort': PORTS,
35                  'OS::TripleO::Controller::Ports::InternalApiPort': PORTS,
36                  'OS::TripleO::Compute::Ports::InternalApiPort': PORTS}
37
38 # A list of flags that will be set to true when IPv6 is enabled
39 IPV6_FLAGS = ["NovaIPv6", "MongoDbIPv6", "CorosyncIPv6", "CephIPv6",
40               "RabbitIPv6", "MemcachedIPv6"]
41
42
43 class NetworkEnvironment:
44     """
45     This class creates a Network Environment to be used in TripleO Heat
46     Templates.
47
48     The class builds upon an existing network-environment file and modifies
49     based on a NetworkSettings object.
50     """
51     def __init__(self, net_settings, filename):
52         with open(filename, 'r') as net_env_fh:
53             self.netenv_obj = yaml.load(net_env_fh)
54             self._update_net_environment(net_settings)
55
56     def _update_net_environment(self, settings_obj):
57         """
58         Updates Network Environment according to Network Settings
59         :param: network settings object
60         :return:  None
61         """
62         if not settings_obj:
63             raise NetworkEnvException("Network Settings does not exist")
64
65         net_settings = settings_obj.get_network_settings()
66         enabled_networks = settings_obj.get_enabled_networks()
67         param_def = 'parameter_defaults'
68         reg = 'resource_registry'
69         for key, prefix in TENANT_RESOURCES.items():
70             if prefix is None:
71                 prefix = ''
72             m = re.split('%s/\w+\.yaml' % prefix, self.netenv_obj[reg][key])
73             if m is not None:
74                 tht_dir = m[0]
75                 break
76         if not tht_dir:
77             raise NetworkEnvException('Unable to parse THT Directory')
78
79         admin_cidr = net_settings[ADMIN_NETWORK]['cidr']
80         admin_prefix = str(admin_cidr.prefixlen)
81         self.netenv_obj[param_def]['ControlPlaneSubnetCidr'] = admin_prefix
82         self.netenv_obj[param_def]['ControlPlaneDefaultRoute'] = \
83             net_settings[ADMIN_NETWORK]['provisioner_ip']
84         public_cidr = net_settings[PUBLIC_NETWORK]['cidr']
85         self.netenv_obj[param_def]['ExternalNetCidr'] = str(public_cidr)
86         if net_settings[PUBLIC_NETWORK]['vlan'] != 'native':
87             self.netenv_obj[param_def]['NeutronExternalNetworkBridge'] = '""'
88             self.netenv_obj[param_def]['ExternalNetworkVlanID'] = \
89                 net_settings[PUBLIC_NETWORK]['vlan']
90         public_range = \
91             net_settings[PUBLIC_NETWORK]['usable_ip_range'].split(',')
92         self.netenv_obj[param_def]['ExternalAllocationPools'] = \
93             [{'start':
94               public_range[0],
95               'end': public_range[1]
96               }]
97         self.netenv_obj[param_def]['ExternalInterfaceDefaultRoute'] = \
98             net_settings[PUBLIC_NETWORK]['gateway']
99         self.netenv_obj[param_def]['EC2MetadataIp'] = \
100             net_settings[ADMIN_NETWORK]['provisioner_ip']
101         self.netenv_obj[param_def]['DnsServers'] = net_settings['dns_servers']
102
103         if public_cidr.version == 6:
104             postfix = '/external_v6.yaml'
105         else:
106             postfix = '/external.yaml'
107
108         for key, prefix in EXTERNAL_RESOURCES.items():
109             if prefix is None:
110                 prefix = ''
111             self.netenv_obj[reg][key] = tht_dir + prefix + postfix
112
113         if PRIVATE_NETWORK in enabled_networks:
114             priv_range = net_settings[PRIVATE_NETWORK][
115                 'usable_ip_range'].split(',')
116             self.netenv_obj[param_def]['TenantAllocationPools'] = \
117                 [{'start':
118                   priv_range[0],
119                   'end': priv_range[1]
120                   }]
121             priv_cidr = net_settings[PRIVATE_NETWORK]['cidr']
122             self.netenv_obj[param_def]['TenantNetCidr'] = str(priv_cidr)
123             if priv_cidr.version == 6:
124                 postfix = '/tenant_v6.yaml'
125             else:
126                 postfix = '/tenant.yaml'
127             if net_settings[PRIVATE_NETWORK]['vlan'] != 'native':
128                 self.netenv_obj[param_def]['TenantNetworkVlanID'] = \
129                     net_settings[PRIVATE_NETWORK]['vlan']
130         else:
131             postfix = '/noop.yaml'
132
133         for key, prefix in TENANT_RESOURCES.items():
134             if prefix is None:
135                 prefix = ''
136             self.netenv_obj[reg][key] = tht_dir + prefix + postfix
137
138         if STORAGE_NETWORK in enabled_networks:
139             storage_range = net_settings[STORAGE_NETWORK][
140                 'usable_ip_range'].split(',')
141             self.netenv_obj[param_def]['StorageAllocationPools'] = \
142                 [{'start':
143                   storage_range[0],
144                   'end':
145                   storage_range[1]
146                   }]
147             storage_cidr = net_settings[STORAGE_NETWORK]['cidr']
148             self.netenv_obj[param_def]['StorageNetCidr'] = str(storage_cidr)
149             if storage_cidr.version == 6:
150                 postfix = '/storage_v6.yaml'
151             else:
152                 postfix = '/storage.yaml'
153             if net_settings[STORAGE_NETWORK]['vlan'] != 'native':
154                 self.netenv_obj[param_def]['StorageNetworkVlanID'] = \
155                     net_settings[STORAGE_NETWORK]['vlan']
156         else:
157             postfix = '/noop.yaml'
158
159         for key, prefix in STORAGE_RESOURCES.items():
160             if prefix is None:
161                 prefix = ''
162             self.netenv_obj[reg][key] = tht_dir + prefix + postfix
163
164         if API_NETWORK in enabled_networks:
165             api_range = net_settings[API_NETWORK][
166                 'usable_ip_range'].split(',')
167             self.netenv_obj[param_def]['InternalApiAllocationPools'] = \
168                 [{'start': api_range[0],
169                   'end': api_range[1]
170                   }]
171             api_cidr = net_settings[API_NETWORK]['cidr']
172             self.netenv_obj[param_def]['InternalApiNetCidr'] = str(api_cidr)
173             if api_cidr.version == 6:
174                 postfix = '/internal_api_v6.yaml'
175             else:
176                 postfix = '/internal_api.yaml'
177             if net_settings[API_NETWORK]['vlan'] != 'native':
178                 self.netenv_obj[param_def]['InternalApiNetworkVlanID'] = \
179                     net_settings[API_NETWORK]['vlan']
180         else:
181             postfix = '/noop.yaml'
182
183         for key, prefix in API_RESOURCES.items():
184             if prefix is None:
185                 prefix = ''
186             self.netenv_obj[reg][key] = tht_dir + prefix + postfix
187
188         # Set IPv6 related flags to True. Not that we do not set those to False
189         # when IPv4 is configured, we'll use the default or whatever the user
190         # may have set.
191         if settings_obj.get_ip_addr_family() == 6:
192             for flag in IPV6_FLAGS:
193                 self.netenv_obj[param_def][flag] = True
194
195     def get_netenv_settings(self):
196         """
197         Getter for netenv settings
198         :return: Dictionary of network environment settings
199         """
200         return self.netenv_obj
201
202
203 class NetworkEnvException(Exception):
204     def __init__(self, value):
205         self.value = value
206
207     def __str__(self):
208             return self.value