Add CaaS related network type queries
[ta/config-manager.git] / cmdatahandlers / src / cmdatahandlers / network_profiles / config.py
1 # Copyright 2019 Nokia
2
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 from cmdatahandlers.api import configerror
16 from cmdatahandlers.api import config
17 from cmdatahandlers.api import utils
18
19
20 class Config(config.Config):
21     def __init__(self, confman):
22         super(Config, self).__init__(confman)
23         self.ROOT = 'cloud.network_profiles'
24         self.DOMAIN = 'network_profiles'
25
26     def init(self):
27         pass
28
29     def validate(self):
30         self.validate_root()
31         self._validate_network_profiles()
32
33     def _validate_network_profiles(self):
34         profiles = self.get_network_profiles()
35         utils.validate_list_items_unique(profiles)
36         for profile in profiles:
37             self._validate_network_profile(profile)
38
39     def _validate_network_profile(self, profile):
40         bondinginterfaces = None
41         try:
42             bondinginterfaces = self.get_profile_bonding_interfaces(profile)
43         except configerror.ConfigError:
44             pass
45
46         if bondinginterfaces:
47             utils.validate_list_items_unique(bondinginterfaces)
48
49             for bond in bondinginterfaces:
50                 bondedinterfaces = self.get_profile_bonded_interfaces(
51                     profile, bond)
52                 utils.validate_list_items_unique(bondedinterfaces)
53                 if len(bondedinterfaces) < 2:
54                     raise configerror.ConfigError(
55                         'Number of bonded interfaces should be at least 2 in %s' % bond)
56
57         mappedinterfaces = self.get_profile_network_mapped_interfaces(profile)
58
59         utils.validate_list_items_unique(mappedinterfaces)
60
61         netconf = self.confman.get_networking_config_handler()
62         validnetworks = netconf.get_networks()
63         for interface in mappedinterfaces:
64             networks = self.get_profile_interface_mapped_networks(
65                 profile, interface)
66             utils.validate_list_items_unique(networks)
67             for network in networks:
68                 if network not in validnetworks:
69                     raise configerror.ConfigError(
70                         'Network %s is not valid' % network)
71
72     def is_valid_profile(self, profile):
73         """
74         Check if given profile exists
75
76         Arguments:
77             The profile name
78
79         Returns:
80             True if given profile exists
81
82         Raises:
83             ConfigError in-case of an error
84         """
85         self.validate_root()
86         profiles = self.get_network_profiles()
87         if profile not in profiles:
88             raise configerror.ConfigError('Invalid profile name %s' % profile)
89
90     def get_network_profiles(self):
91         """
92         Get the network profiles list
93
94         Returns:
95             A list of network profile(s) names
96
97         Raises:
98             ConfigError in-case of an error
99         """
100         self.validate_root()
101         return self.config[self.ROOT].keys()
102
103     def get_profile_linux_bonding_options(self, profile):
104         """
105         Get the linux bonding options of a profile
106
107         Arguments:
108             The profile name
109
110         Returns:
111             The linux bonding options
112
113         Raises:
114             ConfigError in-case of an error
115         """
116         self.is_valid_profile(profile)
117
118         if 'linux_bonding_options' not in self.config[self.ROOT][profile]:
119             raise configerror.ConfigError(
120                 'profile %s has no linux bonding options' %
121                 profile)
122
123         return self.config[self.ROOT][profile]['linux_bonding_options']
124
125     def get_profile_bonding_interfaces(self, profile):
126         """
127         Get the bonding interfaces in a profile
128
129         Arguments:
130             The profile name
131
132         Returns:
133             A list of bonding interfaces names
134
135         Raises:
136             ConfigError in-case of an error
137         """
138         self.is_valid_profile(profile)
139
140         if 'bonding_interfaces' not in self.config[self.ROOT][profile]:
141             raise configerror.ConfigError(
142                 'Profile %s has no bonding interfaces' %
143                 profile)
144
145         return self.config[self.ROOT][profile]['bonding_interfaces'].keys()
146
147     def get_profile_bonded_interfaces(self, profile, bond):
148         """
149         Get the bonded interfaces in bond interface
150
151         Arguments:
152             The name of the profile
153             The name of the bond interface
154
155         Returns:
156             A list of bonded interfaces names
157
158         Raises:
159             ConfigError in-case of an error
160         """
161         self.validate_root()
162         bondinterfaces = self.get_profile_bonding_interfaces(profile)
163         if bond not in bondinterfaces:
164             raise configerror.ConfigError(
165                 'Invalid bond interface name %s in profile %s' %
166                 (bond, profile))
167
168         return self.config[self.ROOT][profile]['bonding_interfaces'][bond]
169
170     def get_profile_network_mapped_interfaces(self, profile):
171         """
172         Get the network mapped interfaces
173
174         Arguments:
175             The profile name
176
177         Returns:
178             A list of network mapped interfaces
179
180         Raises:
181             ConfigError in-case of an error
182         """
183         self.is_valid_profile(profile)
184
185         if 'interface_net_mapping' not in self.config[self.ROOT][profile]:
186             raise configerror.ConfigError(
187                 'Profile %s has now interface to network mapping' %
188                 profile)
189
190         return self.config[self.ROOT][profile]['interface_net_mapping'].keys()
191
192     def get_profile_interface_mapped_networks(self, profile, interface):
193         """
194         Get the networks mapped to a specific interface
195
196         Arguments:
197             The profile name
198             The interface name
199
200         Returns:
201             A list of network names
202
203         Raises:
204             ConfigError in-case of an error
205         """
206         self.is_valid_profile(profile)
207         mappedinterfaces = self.get_profile_network_mapped_interfaces(profile)
208         if interface not in mappedinterfaces:
209             raise configerror.ConfigError(
210                 'Interface %s is not valid for profile %s' %
211                 (interface, profile))
212
213         return self.config[self.ROOT][profile]['interface_net_mapping'][interface]
214
215     def get_profile_provider_network_interfaces(self, profile):
216         """
217         Get the list of provider network interfaces
218
219         Arguments:
220             The profile name
221
222         Returns:
223             A sorted list of network interface names
224
225         Raises:
226             ConfigError in-case of an error
227         """
228         self.is_valid_profile(profile)
229         if 'provider_network_interfaces' not in self.config[self.ROOT][profile]:
230             raise configerror.ConfigError(
231                 'Profile %s has no provider network interfaces' %
232                 profile)
233
234         return sorted(self.config[self.ROOT][profile]
235                       ['provider_network_interfaces'].keys())
236
237     def _get_profile_provider_network_interface_dict(self, profile, interface):
238         self.is_valid_profile(profile)
239         interfaces = self.get_profile_provider_network_interfaces(profile)
240         if interface not in interfaces:
241             raise configerror.ConfigError(
242                 'Profile %s has no provider interface with name %s' %
243                 (profile, interface))
244
245         return self.config[self.ROOT][profile]['provider_network_interfaces'][interface]
246
247     def get_profile_provider_network_interface_type(self, profile, interface):
248         """
249         Get the type of a provider network interface
250
251         Arguments:
252             The profile name
253             The interface name
254
255         Returns:
256             The type of the network interface
257
258         Raises:
259             ConfigError in-case of an error
260         """
261         iface_dict = self._get_profile_provider_network_interface_dict(
262             profile, interface)
263         if 'type' not in iface_dict:
264             raise configerror.ConfigError(
265                 'Provider network interface %s in profile %s does not have a type!' %
266                 (interface, profile))
267
268         return iface_dict['type']
269
270     def set_profile_provider_network_interface_type(self, profile, interface, type):
271         """
272         Set provider network type
273
274         Arguments:
275             The profile name
276             The interface name
277             The type of provider network
278
279         Raises:
280             ConfigError in-case of an error
281         """
282         iface_dict = self._get_profile_provider_network_interface_dict(
283             profile, interface)
284         if not isinstance(type, basestring):
285             raise configerror.ConfigError(
286                 'Profile %s has invalid provider network type for interface %s: %s' %
287                 (profile, interface, type))
288
289         iface_dict['type'] = type
290
291     def is_provider_network_type_caas(self, profile, interface):
292         """
293         Is provider network type caas
294
295         Arguments:
296             The profile name
297             The interface name
298
299         Returns:
300             True if provider network is for CaaS
301
302         Raises:
303             ConfigError in-case of an error
304         """
305         return self.get_profile_provider_network_interface_type(profile, interface) == 'caas'
306
307     def get_profile_provider_interface_networks(self, profile, interface):
308         """
309         Get provider networks for the interface
310
311         Arguments:
312             The profile name
313             The interface name
314
315         Returns:
316             A list of provider network names
317
318         Raises:
319             ConfigError in-case of an error
320         """
321         iface_dict = self._get_profile_provider_network_interface_dict(
322             profile, interface)
323         if 'provider_networks' not in iface_dict:
324             raise configerror.ConfigError(
325                 'Profile %s has no provider networks for interface %s' %
326                 (profile, interface))
327
328         return iface_dict['provider_networks']
329
330     def get_profile_sriov_provider_networks(self, profile):
331         """
332         Get SR-IOV provider networks
333
334         Arguments:
335             The profile name
336
337         Returns:
338             A list of SR-IOV provider network names
339
340         Raises:
341             ConfigError in-case of an error
342         """
343         self.is_valid_profile(profile)
344         if 'sriov_provider_networks' not in self.config[self.ROOT][profile]:
345             raise configerror.ConfigError(
346                 'Profile %s has no SR-IOV provider networks' %
347                 profile)
348
349         return self.config[self.ROOT][profile]['sriov_provider_networks'].keys()
350
351     def get_profile_sriov_network_interfaces(self, profile, network):
352         """
353         Get SR-IOV provider network interfaces
354
355         Arguments:
356             The profile name
357             The SR-IOV network name
358
359         Returns:
360             A list of SR-IOV provider network interface names
361
362         Raises:
363             ConfigError in-case of an error
364         """
365         self._validate_network_is_sriov_provider_network(profile, network)
366
367         if 'interfaces' not in self.config[self.ROOT][profile]['sriov_provider_networks'][network]:
368             raise configerror.ConfigError(
369                 'Profile %s has no SR-IOV provider network interfaces for the network %s' %
370                 (profile, network))
371
372         return self.config[self.ROOT][profile]['sriov_provider_networks'][network]['interfaces']
373
374     def set_profile_sriov_provider_network_type(self, profile, network, type):
375         """
376         Set SR-IOV provider network type
377
378         Arguments:
379             The profile name
380             The SR-IOV network name
381             The type of SR-IOV network
382
383         Raises:
384             ConfigError in-case of an error
385         """
386         self._validate_network_is_sriov_provider_network(profile, network)
387
388         if not isinstance(type, basestring):
389             raise configerror.ConfigError(
390                 'Profile %s has invalid SR-IOV provider network type for the network %s: %s' %
391                 (profile, network, type))
392
393         self.config[self.ROOT][profile]['sriov_provider_networks'][network]['type'] = type
394
395     def is_sriov_network_trusted(self, profile, network):
396         """
397         Is SR-IOV provider network trusted (VF parameter)
398
399         Arguments:
400             The profile name
401             The SR-IOV network name
402
403         Returns:
404             True if VFs should be configured as trusted in this network
405
406         Raises:
407             ConfigError in-case of an error
408         """
409         self._validate_network_is_sriov_provider_network(profile, network)
410
411         return self.config[self.ROOT][profile]['sriov_provider_networks'][network].get('trusted') is True
412
413     def is_sriov_network_type_caas(self, profile, network):
414         """
415         Is SR-IOV network type caas
416
417         Arguments:
418             The profile name
419             The SR-IOV network name
420
421         Returns:
422             True if SR-IOV network is for CaaS
423
424         Raises:
425             ConfigError in-case of an error
426         """
427         self._validate_network_is_sriov_provider_network(profile, network)
428
429         return self.config[self.ROOT][profile]['sriov_provider_networks'][network].get('type') == 'caas'
430
431     def _validate_network_is_sriov_provider_network(self, profile, network):
432         if network not in self.get_profile_sriov_provider_networks(profile):
433             raise configerror.ConfigError(
434                 'Profile %s has no SR-IOV provider network %s' %
435                 (profile, network))
436
437     def get_profile(self, name):
438         """
439         Get the network profile data
440
441         Arguments:
442             The profile name
443
444         Returns:
445             A dict of network profile data
446
447         """
448         self.is_valid_profile(name)
449         return self.config[self.ROOT][name]
450
451     def dump(self):
452         """ Dump all network profiles data. """
453
454         self.validate_root()
455         return self.config[self.ROOT]
456
457     def add_profile(self, name, profile):
458         """ Add network profile.
459
460             Parameters
461             ----------
462             name : str, profile name.
463             profile : dict, profile data
464
465         """
466         if name in self.config[self.ROOT]:
467             raise configerror.ConfigError('Profile %s already exists' % name)
468
469         data = {}
470         data[name] = profile
471         self.config[self.ROOT].update(data)
472
473     def delete_profile(self, name):
474         """ Delete network profile.
475
476             Parameters
477             ----------
478             name : str, profile name.
479
480         """
481         self.is_valid_profile(name)
482         self.config[self.ROOT].pop(name)