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
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
19 from cmdatahandlers.api import validation
20 from cmframework.apis import cmvalidator
21 from cmdatahandlers.api import utils
24 class NetworkProfilesValidation(cmvalidator.CMValidator):
25 SUBSCRIPTION = r'^cloud\.network_profiles|cloud\.networking$'
26 DOMAIN = 'cloud.network_profiles'
27 NETWORKING = 'cloud.networking'
29 MAX_IFACE_NAME_LEN = 15
30 IFACE_NAME_MATCH = r'^[a-z][\da-z]+$'
31 BOND_NAME_MATCH = r'^bond[\d]+$'
33 INTERFACE_NET_MAPPING = 'interface_net_mapping'
34 PROVIDER_NETWORK_INTERFACES = 'provider_network_interfaces'
35 PROVIDER_NETWORKS = 'provider_networks'
36 SRIOV_PROVIDER_NETWORKS = 'sriov_provider_networks'
37 INTERFACES = 'interfaces'
41 DPDK_MAX_RX_QUEUES = 'dpdk_max_rx_queues'
42 BONDING_INTERFACES = 'bonding_interfaces'
43 LINUX_BONDING_OPTIONS = 'linux_bonding_options'
44 OVS_BONDING_OPTIONS = 'ovs_bonding_options'
47 TYPE_OPENSTACK = 'openstack'
49 TYPE_OVS_DPDK = 'ovs-dpdk'
50 TYPE_OVS_OFFLOAD_SRIOV = "ovs-offload-sriov"
51 TYPE_OVS_OFFLOAD_VIRTIO = "ovs-offload-virtio"
52 VALID_PROVIDER_TYPES = [TYPE_CAAS,
55 TYPE_OVS_OFFLOAD_SRIOV,
56 TYPE_OVS_OFFLOAD_VIRTIO]
57 SINGLE_NIC_UNSUPPORTED_TYPES = [TYPE_CAAS, TYPE_OVS_DPDK]
58 VALID_SRIOV_TYPES = [TYPE_CAAS, TYPE_OPENSTACK]
60 MODE_LACP = 'mode=lacp'
61 MODE_LACP_LAYER34 = 'mode=lacp-layer34'
62 MODE_AB = 'mode=active-backup'
63 VALID_BONDING_OPTIONS = [MODE_LACP, MODE_LACP_LAYER34, MODE_AB]
65 VLAN_RANGES = 'vlan_ranges'
69 NETWORK_DOMAINS = 'network_domains'
73 INPUT_ERR_CONTEXT = 'validate_set() input'
74 ERR_INPUT_NOT_DICT = 'Invalid %s, not a dictionary' % INPUT_ERR_CONTEXT
76 ERR_MISSING = 'Missing {1} configuration in {0}'
77 ERR_NOT_DICT = 'Invalid {1} value in {0}: Empty or not a dictionary'
78 ERR_NOT_LIST = 'Invalid {1} value in {0}: Empty, contains duplicates or not a list'
79 ERR_NOT_STR = 'Invalid {1} value in {0}: Not a string'
80 ERR_NOT_INT = 'Invalid {1} value in {0}: Not an integer'
81 ERR_NOT_BOOL = 'Invalid {1} value in {0}: Not a boolean value'
83 ERR_INVALID_IFACE_NAME = 'Invalid interface name in {}'
84 ERR_IFACE_NAME_LEN = 'Too long interface name in {}, max %s chars' % MAX_IFACE_NAME_LEN
85 ERR_IFACE_VLAN = 'Interface in {0} cannot be vlan interface: {1}'
86 ERR_IFACE_BOND = 'Interface in {0} cannot be bond interface: {1}'
87 ERR_IFACE_NOT_BOND = 'Invalid bonding interface name {1} in {0}'
88 ERR_NET_MAPPING_CONFLICT = 'Network {1} mapped to multiple interfaces in {0}'
89 ERR_UNTAGGED_INFRA_CONFLICT = 'Multiple untagged networks on interface {1} in {0}'
90 ERR_UNTAGGED_MTU_SIZE = 'Untagged network {1} in {0} has too small MTU, ' + \
91 'VLAN tagged networks with bigger MTU exists on the same interface'
93 ERR_INVALID_PROVIDER_TYPE = \
94 'Invalid provider network type for interface {}, valid types: %s' % \
96 ERR_INVALID_SRIOV_TYPE = \
97 'Invalid sr-iov network type for network {}, valid types: %s' % \
100 ERR_DPDK_MAX_RX_QUEUES = 'Invalid %s value {}, must be positive integer' % DPDK_MAX_RX_QUEUES
101 ERR_MISSPLACED_MTU = 'Missplaced MTU inside %s interface {}' % PROVIDER_NETWORK_INTERFACES
102 ERR_OVS_TYPE_CONFLICT = 'Cannot have both %s and %s types of provider networks in {}' % \
103 (TYPE_OVS, TYPE_OVS_DPDK)
104 ERR_DPDK_SRIOV_CONFLICT = 'Cannot have both %s and sr-iov on same interface in {}' % \
106 ERR_OFFLOAD_SRIOV_CONFLICT = 'Cannot have both %s and sr-iov on same profile in {}' % \
107 TYPE_OVS_OFFLOAD_SRIOV
108 ERR_OFFLOAD_DPDK_CONFLICT = 'Cannot have both %s and %s types of provider networks in {}' % \
109 (TYPE_OVS_OFFLOAD_SRIOV, TYPE_OVS_DPDK)
111 ERR_INVALID_BONDING_OPTIONS = 'Invalid {1} in {0}, valid options: %s' % VALID_BONDING_OPTIONS
112 ERR_MISSING_BOND = 'Missing bonding interface definition for {1} in {0}'
113 ERR_LACP_SLAVE_COUNT = 'Invalid bonding slave interface count for {1} in {0} ' + \
114 'at least two interfaces required with %s' % MODE_LACP
115 ERR_AB_SLAVE_COUNT = 'Invalid bonding slave interface count for {1} in {0}, ' + \
116 'exactly two interfaces required with %s' % MODE_AB
117 ERR_SLAVE_CONFLICT = 'Same interface mapped to multiple bond interfaces in {}'
118 ERR_SLAVE_IN_NET = 'Network physical interface {1} mapped also as part of bond in {0}'
120 ERR_SRIOV_MTU_SIZE = 'SR-IOV network {0} MTU {1} cannot be greater than interface {2} MTU {3}'
121 ERR_SRIOV_INFRA_VLAN_CONFLICT = \
122 'SR-IOV network {} vlan range is conflicting with infra network vlan'
123 ERR_SRIOV_PROVIDER_VLAN_CONFLICT = \
124 'SR-IOV network {} vlan range is conflicting with other provider network vlan'
125 ERR_SINGLE_NIC_VIOLATION = \
126 'Provider and infra networks on the same interface in {}: ' + \
127 'Supported only if all networks on the same interface'
128 ERR_SINGLE_NIC_PROVIDER_TYPE = \
129 'Provider and infra networks on the same interface in {0}: ' + \
130 'Not supported for {1} type of provider networks'
131 ERR_INFRA_PROVIDER_VLAN_CONFLICT = \
132 'Provider network {} vlan range is conflicting with infra network vlan'
133 ERR_INFRA_PROVIDER_UNTAGGED_CONFLICT = \
134 'Sharing untagged infra and provider network {} not supported'
135 ERR_SRIOV_LACP_CONFLICT = 'Bonding mode %s not supported with SR-IOV networks' % MODE_LACP
136 ERR_SRIOV_IFACE_CONFLICT = 'Same interface mapped to multiple SR-IOV networks in {}'
137 ERR_VF_COUNT = 'SR-IOV network {} %s must be positive integer' % VF_COUNT
139 ERR_PROVIDER_VLAN_CONFLICT = 'Provider network vlan ranges conflicting on interface {}'
142 def err_input_not_dict():
143 err = NetworkProfilesValidation.ERR_INPUT_NOT_DICT
144 raise validation.ValidationError(err)
147 def err_missing(context, key):
148 err = NetworkProfilesValidation.ERR_MISSING.format(context, key)
149 raise validation.ValidationError(err)
152 def err_not_dict(context, key):
153 err = NetworkProfilesValidation.ERR_NOT_DICT.format(context, key)
154 raise validation.ValidationError(err)
157 def err_not_list(context, key):
158 err = NetworkProfilesValidation.ERR_NOT_LIST.format(context, key)
159 raise validation.ValidationError(err)
162 def err_not_str(context, key):
163 raise validation.ValidationError(NetworkProfilesValidation.ERR_NOT_STR.format(context, key))
166 def err_not_int(context, key):
167 raise validation.ValidationError(NetworkProfilesValidation.ERR_NOT_INT.format(context, key))
170 def err_not_bool(context, key):
171 err = NetworkProfilesValidation.ERR_NOT_BOOL.format(context, key)
172 raise validation.ValidationError(err)
175 def err_invalid_iface_name(context):
176 err = NetworkProfilesValidation.ERR_INVALID_IFACE_NAME.format(context)
177 raise validation.ValidationError(err)
180 def err_iface_name_len(context):
181 err = NetworkProfilesValidation.ERR_IFACE_NAME_LEN.format(context)
182 raise validation.ValidationError(err)
185 def err_iface_vlan(context, iface):
186 err = NetworkProfilesValidation.ERR_IFACE_VLAN.format(context, iface)
187 raise validation.ValidationError(err)
190 def err_iface_bond(context, iface):
191 err = NetworkProfilesValidation.ERR_IFACE_BOND.format(context, iface)
192 raise validation.ValidationError(err)
195 def err_provnet_type(iface):
196 err = NetworkProfilesValidation.ERR_INVALID_PROVIDER_TYPE.format(iface)
197 raise validation.ValidationError(err)
200 def err_sriov_type(network):
201 err = NetworkProfilesValidation.ERR_INVALID_SRIOV_TYPE.format(network)
202 raise validation.ValidationError(err)
205 def err_dpdk_max_rx_queues(value):
206 err = NetworkProfilesValidation.ERR_DPDK_MAX_RX_QUEUES.format(value)
207 raise validation.ValidationError(err)
210 def err_missplaced_mtu(iface):
211 err = NetworkProfilesValidation.ERR_MISSPLACED_MTU.format(iface)
212 raise validation.ValidationError(err)
215 def err_iface_not_bond(context, iface):
216 err = NetworkProfilesValidation.ERR_IFACE_NOT_BOND.format(context, iface)
217 raise validation.ValidationError(err)
220 def err_bonding_options(profile, options_type):
221 err = NetworkProfilesValidation.ERR_INVALID_BONDING_OPTIONS.format(profile, options_type)
222 raise validation.ValidationError(err)
225 def err_missing_bond_def(profile, iface):
226 err = NetworkProfilesValidation.ERR_MISSING_BOND.format(profile, iface)
227 raise validation.ValidationError(err)
230 def err_lacp_slave_count(profile, iface):
231 err = NetworkProfilesValidation.ERR_LACP_SLAVE_COUNT.format(profile, iface)
232 raise validation.ValidationError(err)
235 def err_ab_slave_count(profile, iface):
236 err = NetworkProfilesValidation.ERR_AB_SLAVE_COUNT.format(profile, iface)
237 raise validation.ValidationError(err)
240 def err_slave_conflict(profile):
241 err = NetworkProfilesValidation.ERR_SLAVE_CONFLICT.format(profile)
242 raise validation.ValidationError(err)
245 def err_slave_in_net(profile, iface):
246 err = NetworkProfilesValidation.ERR_SLAVE_IN_NET.format(profile, iface)
247 raise validation.ValidationError(err)
250 def err_ovs_type_conflict(profile):
251 err = NetworkProfilesValidation.ERR_OVS_TYPE_CONFLICT.format(profile)
252 raise validation.ValidationError(err)
255 def err_offload_dpdk_conflict(profile):
256 err = NetworkProfilesValidation.ERR_OFFLOAD_DPDK_CONFLICT.format(profile)
257 raise validation.ValidationError(err)
260 def err_dpdk_sriov_conflict(profile):
261 err = NetworkProfilesValidation.ERR_DPDK_SRIOV_CONFLICT.format(profile)
262 raise validation.ValidationError(err)
265 def err_offload_sriov_conflict(profile):
266 err = NetworkProfilesValidation.ERR_OFFLOAD_SRIOV_CONFLICT.format(profile)
267 raise validation.ValidationError(err)
270 def err_net_mapping_conflict(profile, network):
271 err = NetworkProfilesValidation.ERR_NET_MAPPING_CONFLICT.format(profile, network)
272 raise validation.ValidationError(err)
275 def err_untagged_infra_conflict(profile, iface):
276 err = NetworkProfilesValidation.ERR_UNTAGGED_INFRA_CONFLICT.format(profile, iface)
277 raise validation.ValidationError(err)
280 def err_untagged_mtu_size(context, network):
281 err = NetworkProfilesValidation.ERR_UNTAGGED_MTU_SIZE.format(context, network)
282 raise validation.ValidationError(err)
285 def err_sriov_mtu_size(sriov_net, sriov_mtu, phys_iface, iface_mtu):
286 err = NetworkProfilesValidation.ERR_SRIOV_MTU_SIZE.format(sriov_net, sriov_mtu,
287 phys_iface, iface_mtu)
288 raise validation.ValidationError(err)
291 def err_sriov_infra_vlan_conflict(network):
292 err = NetworkProfilesValidation.ERR_SRIOV_INFRA_VLAN_CONFLICT.format(network)
293 raise validation.ValidationError(err)
296 def err_sriov_provider_vlan_conflict(network):
297 err = NetworkProfilesValidation.ERR_SRIOV_PROVIDER_VLAN_CONFLICT.format(network)
298 raise validation.ValidationError(err)
301 def err_single_nic_violation(profile):
302 err = NetworkProfilesValidation.ERR_SINGLE_NIC_VIOLATION.format(profile)
303 raise validation.ValidationError(err)
306 def err_single_nic_provider_type(profile, provider_type):
307 err = NetworkProfilesValidation.ERR_SINGLE_NIC_PROVIDER_TYPE.format(profile, provider_type)
308 raise validation.ValidationError(err)
311 def err_infra_provider_vlan_conflict(network):
312 err = NetworkProfilesValidation.ERR_INFRA_PROVIDER_VLAN_CONFLICT.format(network)
313 raise validation.ValidationError(err)
316 def err_infra_provider_untagged_conflict(network):
317 err = NetworkProfilesValidation.ERR_INFRA_PROVIDER_UNTAGGED_CONFLICT.format(network)
318 raise validation.ValidationError(err)
321 def err_sriov_lacp_conflict():
322 err = NetworkProfilesValidation.ERR_SRIOV_LACP_CONFLICT
323 raise validation.ValidationError(err)
326 def err_sriov_iface_conflict():
327 err = NetworkProfilesValidation.ERR_SRIOV_IFACE_CONFLICT
328 raise validation.ValidationError(err)
331 def err_vf_count(network):
332 err = NetworkProfilesValidation.ERR_VF_COUNT.format(network)
333 raise validation.ValidationError(err)
336 def err_provider_vlan_conflict(iface):
337 err = NetworkProfilesValidation.ERR_PROVIDER_VLAN_CONFLICT.format(iface)
338 raise validation.ValidationError(err)
342 return isinstance(conf, dict)
345 def is_bond_iface(iface):
346 return re.match(NetworkProfilesValidation.BOND_NAME_MATCH, iface)
349 def is_non_empty_dict(conf):
350 return isinstance(conf, dict) and len(conf) > 0
353 def key_exists(conf_dict, key):
354 return key in conf_dict
357 def val_is_int(conf_dict, key):
358 return isinstance(conf_dict[key], (int, long))
361 def val_is_bool(conf_dict, key):
362 return isinstance(conf_dict[key], bool)
365 def val_is_str(conf_dict, key):
366 return isinstance(conf_dict[key], basestring)
369 def val_is_non_empty_list(conf_dict, key):
370 return (isinstance(conf_dict[key], list) and
371 len(conf_dict[key]) > 0 and
372 len(conf_dict[key]) == len(set(conf_dict[key])))
375 def val_is_non_empty_dict(conf_dict, key):
376 return NetworkProfilesValidation.is_non_empty_dict(conf_dict[key])
379 def key_must_exist(conf_dict, entry, key):
380 if not NetworkProfilesValidation.key_exists(conf_dict[entry], key):
381 NetworkProfilesValidation.err_missing(entry, key)
384 def must_be_str(conf_dict, entry, key):
385 NetworkProfilesValidation.key_must_exist(conf_dict, entry, key)
386 if not NetworkProfilesValidation.val_is_str(conf_dict[entry], key):
387 NetworkProfilesValidation.err_not_str(entry, key)
390 def must_be_list(conf_dict, entry, key):
391 NetworkProfilesValidation.key_must_exist(conf_dict, entry, key)
392 if not NetworkProfilesValidation.val_is_non_empty_list(conf_dict[entry], key):
393 NetworkProfilesValidation.err_not_list(entry, key)
396 def must_be_dict(conf_dict, entry, key):
397 NetworkProfilesValidation.key_must_exist(conf_dict, entry, key)
398 if not NetworkProfilesValidation.val_is_non_empty_dict(conf_dict[entry], key):
399 NetworkProfilesValidation.err_not_dict(entry, key)
402 def exists_as_dict(conf_dict, entry, key):
403 if not NetworkProfilesValidation.key_exists(conf_dict[entry], key):
405 if not NetworkProfilesValidation.val_is_non_empty_dict(conf_dict[entry], key):
406 NetworkProfilesValidation.err_not_dict(entry, key)
410 def exists_as_int(conf_dict, entry, key):
411 if not NetworkProfilesValidation.key_exists(conf_dict[entry], key):
413 if not NetworkProfilesValidation.val_is_int(conf_dict[entry], key):
414 NetworkProfilesValidation.err_not_int(entry, key)
418 def are_overlapping(ranges1, ranges2):
419 for range1 in ranges1:
420 for range2 in ranges2:
421 if not (range1[0] > range2[1] or range1[1] < range2[0]):
426 cmvalidator.CMValidator.__init__(self)
428 self.networking = None
430 def get_subscription_info(self):
431 return self.SUBSCRIPTION
433 def validate_set(self, props):
434 if not self.is_dict(props):
435 self.err_input_not_dict()
437 if not (self.key_exists(props, self.DOMAIN) or
438 self.key_exists(props, self.NETWORKING)):
439 self.err_missing(self.INPUT_ERR_CONTEXT,
440 '{} or {}'.format(self.DOMAIN, self.NETWORKING))
442 if self.key_exists(props, self.DOMAIN):
443 if not props[self.DOMAIN]:
444 self.err_not_dict(self.INPUT_ERR_CONTEXT, self.DOMAIN)
445 self.conf = json.loads(props[self.DOMAIN])
447 self.conf = json.loads(self.get_plugin_client().get_property(self.DOMAIN))
449 if not self.is_non_empty_dict(self.conf):
450 self.err_not_dict(self.INPUT_ERR_CONTEXT, self.DOMAIN)
452 if self.key_exists(props, self.NETWORKING):
453 if not props[self.NETWORKING]:
454 self.err_not_dict(self.INPUT_ERR_CONTEXT, self.NETWORKING)
455 self.networking = json.loads(props[self.NETWORKING])
457 self.networking = json.loads(self.get_plugin_client().get_property(self.NETWORKING))
459 if not self.is_non_empty_dict(self.networking):
460 self.err_not_dict(self.INPUT_ERR_CONTEXT, self.NETWORKING)
465 for profile_name in self.conf:
466 if not self.val_is_non_empty_dict(self.conf, profile_name):
467 self.err_not_dict(self.DOMAIN, profile_name)
468 self.validate_network_profile(profile_name)
470 def validate_network_profile(self, profile_name):
471 self.validate_interface_net_mapping(profile_name)
472 self.validate_bonding_interfaces(profile_name)
473 self.validate_bonding_options(profile_name)
474 self.validate_provider_net_ifaces(profile_name)
475 self.validate_network_integrity(profile_name)
476 self.validate_sriov_provider_networks(profile_name)
477 self.validate_provider_networks(profile_name)
479 def validate_interface_net_mapping(self, profile_name):
480 self.must_be_dict(self.conf, profile_name, self.INTERFACE_NET_MAPPING)
482 for iface in self.conf[profile_name][self.INTERFACE_NET_MAPPING]:
483 self.validate_iface_name(self.INTERFACE_NET_MAPPING, iface)
484 self.validate_not_vlan(self.INTERFACE_NET_MAPPING, iface)
485 self.must_be_list(self.conf[profile_name], self.INTERFACE_NET_MAPPING, iface)
486 iface_nets = self.conf[profile_name][self.INTERFACE_NET_MAPPING][iface]
487 self.validate_used_infra_networks_defined(iface_nets)
488 for domain in self.get_network_domains(iface_nets):
489 self.validate_untagged_infra_integrity(iface_nets, iface, profile_name, domain)
490 networks.extend(iface_nets)
491 self.validate_networks_mapped_only_once(profile_name, networks)
493 def validate_used_infra_networks_defined(self, networks):
495 if not self.key_exists(self.networking, net):
496 self.err_missing(self.NETWORKING, net)
497 self.must_be_dict(self.networking, net, self.NETWORK_DOMAINS)
498 for domain in self.networking[net][self.NETWORK_DOMAINS]:
499 self.must_be_dict(self.networking[net], self.NETWORK_DOMAINS, domain)
501 def get_network_domains(self, networks):
504 domains.update(self.networking[net][self.NETWORK_DOMAINS].keys())
507 def validate_untagged_infra_integrity(self, iface_nets, iface, profile_name, network_domain):
511 default_mtu = self.get_default_mtu()
513 for net in iface_nets:
514 if self.key_exists(self.networking[net][self.NETWORK_DOMAINS], network_domain):
515 if not self.key_exists(self.networking[net][self.NETWORK_DOMAINS][network_domain],
517 untagged_infras.append(net)
518 if self.exists_as_int(self.networking, net, self.MTU):
519 untagged_mtu = self.networking[net][self.MTU]
521 untagged_mtu = default_mtu
523 if self.exists_as_int(self.networking, net, self.MTU):
524 mtu = self.networking[net][self.MTU]
527 if mtu > max_vlan_mtu:
530 if not utils.is_virtualized():
531 if len(untagged_infras) > 1:
532 self.err_untagged_infra_conflict(profile_name, iface)
534 if untagged_mtu and untagged_mtu < max_vlan_mtu:
535 self.err_untagged_mtu_size(self.NETWORKING, untagged_infras[0])
537 def validate_bonding_interfaces(self, profile_name):
539 if self.exists_as_dict(self.conf, profile_name, self.BONDING_INTERFACES):
540 for iface in self.conf[profile_name][self.BONDING_INTERFACES]:
541 self.validate_iface_name(self.BONDING_INTERFACES, iface)
542 if not self.is_bond_iface(iface):
543 self.err_iface_not_bond(self.BONDING_INTERFACES, iface)
544 self.must_be_list(self.conf[profile_name], self.BONDING_INTERFACES, iface)
545 for slave in self.conf[profile_name][self.BONDING_INTERFACES][iface]:
546 self.validate_bond_slave(iface, slave)
548 if len(slaves) != len(set(slaves)):
549 self.err_slave_conflict(profile_name)
551 def validate_bond_slave(self, iface, slave):
552 self.validate_iface_name(iface, slave)
553 self.validate_not_vlan(iface, slave)
554 self.validate_not_bond(iface, slave)
556 def validate_not_bond(self, context, iface):
558 self.err_iface_bond(context, iface)
560 def validate_bonding_options(self, profile_name):
561 self.validate_bonding_option(profile_name, self.LINUX_BONDING_OPTIONS)
562 self.validate_bonding_option(profile_name, self.OVS_BONDING_OPTIONS)
564 def validate_bonding_option(self, profile_name, options_type):
565 if self.key_exists(self.conf[profile_name], options_type):
566 if self.conf[profile_name][options_type] not in self.VALID_BONDING_OPTIONS:
567 self.err_bonding_options(profile_name, options_type)
569 def validate_provider_net_ifaces(self, profile_name):
570 if self.exists_as_dict(self.conf, profile_name, self.PROVIDER_NETWORK_INTERFACES):
573 for iface in self.conf[profile_name][self.PROVIDER_NETWORK_INTERFACES]:
574 self.validate_iface_name(self.PROVIDER_NETWORK_INTERFACES, iface)
575 self.validate_not_vlan(self.PROVIDER_NETWORK_INTERFACES, iface)
576 provnet_ifaces_conf = self.conf[profile_name][self.PROVIDER_NETWORK_INTERFACES]
577 self.validate_provider_net_type(provnet_ifaces_conf, iface)
578 self.validate_provider_net_vf_count(provnet_ifaces_conf, iface)
579 self.validate_dpdk_max_rx_queues(provnet_ifaces_conf, iface)
580 self.validate_no_mtu(provnet_ifaces_conf, iface)
581 self.must_be_list(provnet_ifaces_conf, iface, self.PROVIDER_NETWORKS)
582 types.add(provnet_ifaces_conf[iface][self.TYPE])
583 networks.extend(provnet_ifaces_conf[iface][self.PROVIDER_NETWORKS])
584 if self.TYPE_OVS_DPDK in types and self.TYPE_OVS in types:
585 self.err_ovs_type_conflict(profile_name)
586 if self.TYPE_OVS_DPDK in types and self.TYPE_OVS_OFFLOAD_SRIOV in types:
587 self.err_offload_dpdk_conflict(profile_name)
588 self.validate_networks_mapped_only_once(profile_name, networks)
589 self.validate_used_provider_networks_defined(networks)
591 def validate_sriov_provider_networks(self, profile_name):
592 if self.exists_as_dict(self.conf, profile_name, self.SRIOV_PROVIDER_NETWORKS):
593 networks = self.conf[profile_name][self.SRIOV_PROVIDER_NETWORKS]
594 self.validate_used_provider_networks_defined(networks)
596 for network in networks:
597 if (self.exists_as_int(networks, network, self.VF_COUNT) and
598 networks[network][self.VF_COUNT] < 1):
599 self.err_vf_count(network)
600 if (self.key_exists(networks[network], self.TRUSTED) and
601 not self.val_is_bool(networks[network], self.TRUSTED)):
602 self.err_not_bool(network, self.TRUSTED)
603 if (self.key_exists(networks[network], self.TYPE) and
604 networks[network][self.TYPE] not in self.VALID_SRIOV_TYPES):
605 self.err_sriov_type(network)
606 self.must_be_list(networks, network, self.INTERFACES)
607 for iface in networks[network][self.INTERFACES]:
608 sriov_ifaces.append(iface)
609 self.validate_iface_name(network, iface)
610 self.validate_not_vlan(network, iface)
611 self.validate_not_bond(network, iface)
612 self.validate_not_part_of_lacp(self.conf[profile_name], iface)
613 infra_info = self.get_iface_infra_info(self.conf[profile_name], iface)
614 if infra_info is not None:
615 self.validate_shared_sriov_infra(network, iface, infra_info)
616 provider_info = self.get_iface_provider_info(self.conf[profile_name], iface)
617 if provider_info[self.TYPE] == self.TYPE_OVS_DPDK:
618 self.err_dpdk_sriov_conflict(profile_name)
619 if provider_info[self.TYPE] == self.TYPE_OVS_OFFLOAD_SRIOV:
620 self.err_offload_sriov_conflict(profile_name)
621 if provider_info[self.VLAN_RANGES]:
622 self.validate_shared_sriov_provider(network,
623 provider_info[self.VLAN_RANGES])
624 if len(sriov_ifaces) != len(set(sriov_ifaces)):
625 self.err_sriov_iface_conflict()
627 def validate_provider_networks(self, profile_name):
628 if self.key_exists(self.conf[profile_name], self.PROVIDER_NETWORK_INTERFACES):
629 for iface in self.conf[profile_name][self.PROVIDER_NETWORK_INTERFACES]:
630 iface_info = self.conf[profile_name][self.PROVIDER_NETWORK_INTERFACES][iface]
631 vlan_ranges_list = []
632 for network in iface_info[self.PROVIDER_NETWORKS]:
633 vlan_ranges = self.get_vlan_ranges(network)
634 vlan_ranges_list.append(vlan_ranges)
635 infra_info = self.get_iface_infra_info(self.conf[profile_name], iface)
636 if infra_info is not None:
637 if (len(self.conf[profile_name][self.PROVIDER_NETWORK_INTERFACES]) > 1 or
638 len(self.conf[profile_name][self.INTERFACE_NET_MAPPING]) > 1):
639 self.err_single_nic_violation(profile_name)
640 if iface_info[self.TYPE] in self.SINGLE_NIC_UNSUPPORTED_TYPES:
641 self.err_single_nic_provider_type(profile_name, iface_info[self.TYPE])
642 self.validate_shared_infra_provider(network, infra_info, vlan_ranges)
643 for idx, ranges1 in enumerate(vlan_ranges_list):
644 for ranges2 in vlan_ranges_list[(idx+1):]:
645 if self.are_overlapping(ranges1, ranges2):
646 self.err_provider_vlan_conflict(iface)
648 def validate_not_part_of_lacp(self, profile_conf, iface):
649 if self.key_exists(profile_conf, self.PROVIDER_NETWORK_INTERFACES):
650 for prov_iface, prov in profile_conf[self.PROVIDER_NETWORK_INTERFACES].iteritems():
651 if self.is_bond_iface(prov_iface):
652 if iface in profile_conf[self.BONDING_INTERFACES][prov_iface]:
653 bonding_type = self.OVS_BONDING_OPTIONS \
654 if prov[self.TYPE] != self.TYPE_CAAS else self.LINUX_BONDING_OPTIONS
655 if profile_conf[bonding_type] == self.MODE_LACP:
656 self.err_sriov_lacp_conflict()
657 # part of ovs bonding
658 # do not check linux bonding options even if shared with infra networks
660 for infra_iface in profile_conf[self.INTERFACE_NET_MAPPING]:
661 if self.is_bond_iface(infra_iface):
662 if iface in profile_conf[self.BONDING_INTERFACES][infra_iface]:
663 if profile_conf[self.LINUX_BONDING_OPTIONS] == self.MODE_LACP:
664 self.err_sriov_lacp_conflict()
667 def validate_shared_sriov_infra(self, sriov_net, iface, infra_info):
668 sriov_info = self.get_sriov_info(sriov_net)
669 if sriov_info[self.MTU] > infra_info[self.MTU]:
670 self.err_sriov_mtu_size(sriov_net, sriov_info[self.MTU], iface, infra_info[self.MTU])
671 for vlan_range in sriov_info[self.VLAN_RANGES]:
672 for infra_vlan in infra_info[self.VLAN]:
673 if not (infra_vlan < vlan_range[0] or infra_vlan > vlan_range[1]):
674 self.err_sriov_infra_vlan_conflict(sriov_net)
676 def validate_shared_sriov_provider(self, sriov_net, ovs_vlan_ranges):
677 sriov_vlan_ranges = self.get_vlan_ranges(sriov_net)
678 if self.are_overlapping(sriov_vlan_ranges, ovs_vlan_ranges):
679 self.err_sriov_provider_vlan_conflict(sriov_net)
681 def validate_shared_infra_provider(self, provider_net, infra_info, vlan_ranges):
682 if infra_info[self.UNTAGGED]:
683 self.err_infra_provider_untagged_conflict(provider_net)
684 for vlan in infra_info[self.VLAN]:
685 for vlan_range in vlan_ranges:
686 if not (vlan_range[0] > vlan or vlan_range[1] < vlan):
687 self.err_infra_provider_vlan_conflict(provider_net)
689 def get_iface_infra_info(self, profile_conf, iface):
690 infra_info = {self.VLAN: [], self.MTU: 0, self.UNTAGGED: False}
691 default_mtu = self.get_default_mtu()
692 infra_iface = self.get_master_iface(profile_conf, iface)
694 if self.key_exists(profile_conf[self.INTERFACE_NET_MAPPING], infra_iface):
695 for infra in profile_conf[self.INTERFACE_NET_MAPPING][infra_iface]:
696 for domain in self.networking[infra][self.NETWORK_DOMAINS].itervalues():
697 if self.key_exists(domain, self.VLAN):
698 infra_info[self.VLAN].append(domain[self.VLAN])
700 infra_info[self.UNTAGGED] = True
701 if self.exists_as_int(self.networking, infra, self.MTU):
702 mtu = self.networking[infra][self.MTU]
705 if mtu > infra_info[self.MTU]:
706 infra_info[self.MTU] = mtu
708 if infra_info[self.MTU] == 0:
713 def get_iface_provider_info(self, profile_conf, iface):
714 provider_info = {self.TYPE: None, self.VLAN_RANGES: []}
715 provider_iface = self.get_master_iface(profile_conf, iface)
717 if self.key_exists(profile_conf, self.PROVIDER_NETWORK_INTERFACES):
718 if self.key_exists(profile_conf[self.PROVIDER_NETWORK_INTERFACES], provider_iface):
719 iface_info = profile_conf[self.PROVIDER_NETWORK_INTERFACES][provider_iface]
720 provider_info[self.TYPE] = iface_info[self.TYPE]
721 for network in iface_info[self.PROVIDER_NETWORKS]:
722 provider_info[self.VLAN_RANGES].extend(self.get_vlan_ranges(network))
726 def get_master_iface(self, profile_conf, slave_iface):
727 if self.key_exists(profile_conf, self.BONDING_INTERFACES):
728 for bond in profile_conf[self.BONDING_INTERFACES]:
729 if slave_iface in profile_conf[self.BONDING_INTERFACES][bond]:
733 def get_sriov_info(self, network):
734 sriov_info = {self.VLAN_RANGES: []}
735 if self.exists_as_int(self.networking[self.PROVIDER_NETWORKS], network, self.MTU):
736 sriov_info[self.MTU] = self.networking[self.PROVIDER_NETWORKS][network][self.MTU]
738 sriov_info[self.MTU] = self.get_default_mtu()
739 sriov_info[self.VLAN_RANGES] = self.get_vlan_ranges(network)
742 def get_vlan_ranges(self, network):
744 networks = self.networking[self.PROVIDER_NETWORKS]
745 self.must_be_str(networks, network, self.VLAN_RANGES)
746 for vlan_range in networks[network][self.VLAN_RANGES].split(','):
747 vids = vlan_range.split(':')
756 vlan_ranges.append([start, end])
759 def get_default_mtu(self):
760 if (self.key_exists(self.networking, self.MTU) and
761 self.val_is_int(self.networking, self.MTU)):
762 return self.networking[self.MTU]
763 return self.DEFAULT_MTU
765 def validate_iface_name(self, context, iface):
766 if not isinstance(iface, basestring) or not re.match(self.IFACE_NAME_MATCH, iface):
767 self.err_invalid_iface_name(context)
768 if len(iface) > self.MAX_IFACE_NAME_LEN:
769 self.err_iface_name_len(context)
771 def validate_not_vlan(self, context, iface):
773 self.err_iface_vlan(context, iface)
775 def validate_provider_net_type(self, provnet_ifaces_conf, iface):
776 self.must_be_str(provnet_ifaces_conf, iface, self.TYPE)
777 if provnet_ifaces_conf[iface][self.TYPE] not in self.VALID_PROVIDER_TYPES:
778 self.err_provnet_type(iface)
780 def validate_provider_net_vf_count(self, provnet_ifaces_conf, iface):
781 if self.exists_as_int(provnet_ifaces_conf, iface, self.VF_COUNT):
782 value = provnet_ifaces_conf[iface][self.VF_COUNT]
784 self.err_vf_count(iface)
786 def validate_dpdk_max_rx_queues(self, provnet_ifaces_conf, iface):
787 if self.exists_as_int(provnet_ifaces_conf, iface, self.DPDK_MAX_RX_QUEUES):
788 value = provnet_ifaces_conf[iface][self.DPDK_MAX_RX_QUEUES]
790 self.err_dpdk_max_rx_queues(value)
792 def validate_no_mtu(self, provnet_ifaces_conf, iface):
793 if self.key_exists(provnet_ifaces_conf[iface], self.MTU):
794 self.err_missplaced_mtu(iface)
796 def validate_networks_mapped_only_once(self, profile_name, networks):
798 for net in sorted(networks):
800 self.err_net_mapping_conflict(profile_name, net)
803 def validate_used_provider_networks_defined(self, networks):
805 self.key_must_exist(self.networking, self.PROVIDER_NETWORKS, net)
807 def validate_network_integrity(self, profile_name):
809 if self.key_exists(self.conf[profile_name], self.PROVIDER_NETWORK_INTERFACES):
810 for iface in self.conf[profile_name][self.PROVIDER_NETWORK_INTERFACES]:
811 iface_data = self.conf[profile_name][self.PROVIDER_NETWORK_INTERFACES][iface]
812 bonding_type = self.OVS_BONDING_OPTIONS \
813 if iface_data[self.TYPE] != self.TYPE_CAAS else self.LINUX_BONDING_OPTIONS
814 self.validate_net_iface_integrity(profile_name, iface, bonding_type)
815 provider_ifaces.append(iface)
816 for iface in self.conf[profile_name][self.INTERFACE_NET_MAPPING]:
817 if iface not in provider_ifaces:
818 self.validate_net_iface_integrity(profile_name, iface, self.LINUX_BONDING_OPTIONS)
820 def validate_net_iface_integrity(self, profile_name, iface, bonding_type):
821 if self.is_bond_iface(iface):
822 if (not self.key_exists(self.conf[profile_name], self.BONDING_INTERFACES) or
823 iface not in self.conf[profile_name][self.BONDING_INTERFACES]):
824 self.err_missing_bond_def(profile_name, iface)
825 self.key_must_exist(self.conf, profile_name, bonding_type)
826 self.validate_bond_slave_count(profile_name, iface,
827 self.conf[profile_name][bonding_type])
828 elif self.key_exists(self.conf[profile_name], self.BONDING_INTERFACES):
829 for bond in self.conf[profile_name][self.BONDING_INTERFACES]:
830 for slave in self.conf[profile_name][self.BONDING_INTERFACES][bond]:
832 self.err_slave_in_net(profile_name, iface)
834 def validate_bond_slave_count(self, profile_name, iface, bonding_mode):
835 slave_count = len(self.conf[profile_name][self.BONDING_INTERFACES][iface])
836 if bonding_mode == self.MODE_AB and slave_count != 2:
837 self.err_ab_slave_count(profile_name, iface)
838 elif bonding_mode == self.MODE_LACP and slave_count < 2:
839 self.err_lacp_slave_count(profile_name, iface)