correction to a conditional in nic template
[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]['ExternalNetworkVlanID'] = \
88                 net_settings[PUBLIC_NETWORK]['vlan']
89         public_range = \
90             net_settings[PUBLIC_NETWORK]['usable_ip_range'].split(',')
91         self.netenv_obj[param_def]['ExternalAllocationPools'] = \
92             [{'start':
93               public_range[0],
94               'end': public_range[1]
95               }]
96         self.netenv_obj[param_def]['ExternalInterfaceDefaultRoute'] = \
97             net_settings[PUBLIC_NETWORK]['gateway']
98         self.netenv_obj[param_def]['EC2MetadataIp'] = \
99             net_settings[ADMIN_NETWORK]['provisioner_ip']
100         self.netenv_obj[param_def]['DnsServers'] = net_settings['dns_servers']
101
102         if public_cidr.version == 6:
103             postfix = '/external_v6.yaml'
104         else:
105             postfix = '/external.yaml'
106
107         for key, prefix in EXTERNAL_RESOURCES.items():
108             if prefix is None:
109                 prefix = ''
110             self.netenv_obj[reg][key] = tht_dir + prefix + postfix
111
112         if PRIVATE_NETWORK in enabled_networks:
113             priv_range = net_settings[PRIVATE_NETWORK][
114                 'usable_ip_range'].split(',')
115             self.netenv_obj[param_def]['TenantAllocationPools'] = \
116                 [{'start':
117                   priv_range[0],
118                   'end': priv_range[1]
119                   }]
120             priv_cidr = net_settings[PRIVATE_NETWORK]['cidr']
121             self.netenv_obj[param_def]['TenantNetCidr'] = str(priv_cidr)
122             if priv_cidr.version == 6:
123                 postfix = '/tenant_v6.yaml'
124             else:
125                 postfix = '/tenant.yaml'
126             if net_settings[PRIVATE_NETWORK]['vlan'] != 'native':
127                 self.netenv_obj[param_def]['TenantNetworkVlanID'] = \
128                     net_settings[PRIVATE_NETWORK]['vlan']
129         else:
130             postfix = '/noop.yaml'
131
132         for key, prefix in TENANT_RESOURCES.items():
133             if prefix is None:
134                 prefix = ''
135             self.netenv_obj[reg][key] = tht_dir + prefix + postfix
136
137         if STORAGE_NETWORK in enabled_networks:
138             storage_range = net_settings[STORAGE_NETWORK][
139                 'usable_ip_range'].split(',')
140             self.netenv_obj[param_def]['StorageAllocationPools'] = \
141                 [{'start':
142                   storage_range[0],
143                   'end':
144                   storage_range[1]
145                   }]
146             storage_cidr = net_settings[STORAGE_NETWORK]['cidr']
147             self.netenv_obj[param_def]['StorageNetCidr'] = str(storage_cidr)
148             if storage_cidr.version == 6:
149                 postfix = '/storage_v6.yaml'
150             else:
151                 postfix = '/storage.yaml'
152             if net_settings[STORAGE_NETWORK]['vlan'] != 'native':
153                 self.netenv_obj[param_def]['StorageNetworkVlanID'] = \
154                     net_settings[STORAGE_NETWORK]['vlan']
155         else:
156             postfix = '/noop.yaml'
157
158         for key, prefix in STORAGE_RESOURCES.items():
159             if prefix is None:
160                 prefix = ''
161             self.netenv_obj[reg][key] = tht_dir + prefix + postfix
162
163         if API_NETWORK in enabled_networks:
164             api_range = net_settings[API_NETWORK][
165                 'usable_ip_range'].split(',')
166             self.netenv_obj[param_def]['InternalApiAllocationPools'] = \
167                 [{'start': api_range[0],
168                   'end': api_range[1]
169                   }]
170             api_cidr = net_settings[API_NETWORK]['cidr']
171             self.netenv_obj[param_def]['InternalApiNetCidr'] = str(api_cidr)
172             if api_cidr.version == 6:
173                 postfix = '/internal_api_v6.yaml'
174             else:
175                 postfix = '/internal_api.yaml'
176             if net_settings[API_NETWORK]['vlan'] != 'native':
177                 self.netenv_obj[param_def]['InternalApiNetworkVlanID'] = \
178                     net_settings[API_NETWORK]['vlan']
179         else:
180             postfix = '/noop.yaml'
181
182         for key, prefix in API_RESOURCES.items():
183             if prefix is None:
184                 prefix = ''
185             self.netenv_obj[reg][key] = tht_dir + prefix + postfix
186
187         # Set IPv6 related flags to True. Not that we do not set those to False
188         # when IPv4 is configured, we'll use the default or whatever the user
189         # may have set.
190         if settings_obj.get_ip_addr_family() == 6:
191             for flag in IPV6_FLAGS:
192                 self.netenv_obj[param_def][flag] = True
193
194     def get_netenv_settings(self):
195         """
196         Getter for netenv settings
197         :return: Dictionary of network environment settings
198         """
199         return self.netenv_obj
200
201
202 class NetworkEnvException(Exception):
203     def __init__(self, value):
204         self.value = value
205
206     def __str__(self):
207             return self.value