def cb_create(self, tctx, root, service, proplist, self_plan): # Prepare allocation requests for values not provided by the user allocator = BatchAllocator(tctx.username, root, service) # SIRB VLAN if service.sirb_vlan is None: allocator.append(Allocation.type.id, Config.SIRB_VLAN_POOL, Allocation.get_id('SIRB_VLAN', service.service_id)) # LFNC VLAN, ip address if service.lfnc_vlan is None: allocator.append(Allocation.type.id, Config.LFNC_VLAN_POOL, Allocation.get_id('LFNC_VLAN', service.service_id)) if service.lfnc_ip_address is None: allocator.append(Allocation.type.address, Config.LFNC_IP_POOL, Allocation.get_id('LFNC_IP', service.service_id), length=Config.LFNC_IP_LENGTH) # DCI VLAN, subnet for count, dci_vlan in enumerate(islice(chain(service.dci.vlan, repeat(None)), Config.L3_DCI_NUM_VLANS)): if dci_vlan is None: allocator.append(Allocation.type.id, Config.DCI_VLAN_POOL, Allocation.get_id('DCI_VLAN', service.service_id, count)) if (dci_vlan is None) or (dci_vlan.subnet is None): allocator.append(Allocation.type.address, Config.DCI_IP_POOL, Allocation.get_id('DCI_IP', service.service_id, count), length=Config.DCI_IP_LENGTH) if len(allocator) > 0: self.log.info('Allocating: {}'.format(allocator)) allocations = allocator.read() if allocations is None: self.log.info('Resource allocations are not ready') return # Write operational data container with final values for VLANs and IPs # These are either the user-configured values or values assigned by BatchAllocator allocations_iter = iter(allocations) # SIRB VLAN service.auto_values.sirb_vlan = service.sirb_vlan or next(allocations_iter) # LFNC VLAN, ip address service.auto_values.lfnc_vlan = service.lfnc_vlan or next(allocations_iter) service.auto_values.lfnc_ip_address = service.lfnc_ip_address or subnet_first_host(next(allocations_iter)) # DCI VLAN, subnet for dci_vlan in islice(chain(service.dci.vlan, repeat(None)), Config.L3_DCI_NUM_VLANS): dci_vlan_id = dci_vlan.id if dci_vlan is not None else next(allocations_iter) if dci_vlan_id in service.auto_values.dci_vlan: raise NcsServiceError( 'Configured DCI VLAN ID {} is equal to an auto-assigned VLAN ID'.format(dci_vlan_id)) dci_vlan_node = service.auto_values.dci_vlan.create(dci_vlan_id) dci_vlan_node.subnet = (dci_vlan.subnet if dci_vlan is not None else None) or next(allocations_iter) self_plan.set_reached('evpn:resource-allocations') self.log.info('Rendering l3-direct template') service_vars = { 'SITE-LEAF-ASN': root.plant_information.plant[service.dc_name].as_number.leaf_nodes, } apply_template('l3_direct', service, service_vars) self.log.info('Rendering l3 dci template') apply_l3_dci_template(root, service) return proplist
def apply_l2_dci_template(root_context, service_context): for count, vlan in enumerate(service_context.auto_values.dci_vlan, start=1): dci_vars = { 'COUNT': count, 'VLAN-ID': vlan.id, } apply_template('l2_dci', service_context, dci_vars)
def apply_l3_dci_template(root_context, service_context): for count, vlan in enumerate(service_context.auto_values.dci_vlan, start=1): dci_link_net = ip_network(text(vlan.subnet)) dci_link_ip_list = list(dci_link_net.hosts()) if len(dci_link_ip_list) < 2: raise NcsServiceError('VLAN {} subnet must have at least 2 host addresses'.format(vlan.id)) dci_vars = { 'COUNT': count, 'VLAN-ID': vlan.id, 'BDR-IP': dci_link_ip_list[1], 'BDR-LEN': dci_link_net.prefixlen, 'DCI-IP': dci_link_ip_list[0], 'SITE-DCI-ASN': root_context.plant_information.plant[service_context.dc_name].as_number.dci_nodes, } apply_template('l3_dci', service_context, dci_vars)
def cb_create(self, tctx, root, service, proplist, self_plan): # Prepare allocation requests for values not provided by the user allocator = BatchAllocator(tctx.username, root, service) # LFNC VLAN if service.lfnc_vlan is None: allocator.append(Allocation.type.id, Config.LFNC_VLAN_POOL, Allocation.get_id('LFNC_VLAN', service.service_id)) # DCI VLAN for count, dci_vlan in enumerate(islice(chain(service.dci.vlan, repeat(None)), num_l2_dci_vlans(root, service))): if dci_vlan is None: allocator.append(Allocation.type.id, Config.DCI_VLAN_POOL, Allocation.get_id('DCI_VLAN', service.service_id, count)) if len(allocator) > 0: self.log.info('Allocating: {}'.format(allocator)) allocations = allocator.read() if allocations is None: self.log.info('Resource allocations are not ready') return # Write operational data container with final values for VLANs and IPs # These are either the user-configured values or values assigned by BatchAllocator allocations_iter = iter(allocations) # LFNC VLAN service.auto_values.lfnc_vlan = service.lfnc_vlan or next(allocations_iter) # DCI VLAN for dci_vlan in islice(chain(service.dci.vlan, repeat(None)), num_l2_dci_vlans(root, service)): dci_vlan_id = dci_vlan.id if dci_vlan is not None else next(allocations_iter) if dci_vlan_id in service.auto_values.dci_vlan: raise NcsServiceError( 'Configured DCI VLAN ID {} is equal to an auto-assigned VLAN ID'.format(dci_vlan_id)) service.auto_values.dci_vlan.create(dci_vlan_id) self_plan.set_reached('evpn:resource-allocations') self.log.info('Rendering l2-evpl template') service_vars = { 'SITE-LEAF-ASN': root.plant_information.plant[service.dc_name].as_number.leaf_nodes, } apply_template('l2_vpls', service, service_vars) self.log.info('Rendering l2 dci template') apply_l2_dci_template(root, service) return proplist
def cb_create(self, tctx, root, service, proplist, self_plan): template_vars = { 'NVE_SOURCE': root.plant_information.global_config.nve_source_interface, 'PREFIX-TAG': root.plant_information.global_config.tenant_prefix_tag, 'REDIST-STATIC': root.plant_information.global_config.tenant_route_maps. bgp_redistribute_static, 'REDIST-CONNECTED': root.plant_information.global_config.tenant_route_maps. bgp_redistribute_connected, } # Process leaf nodes self.log.info('Rendering L3 leaf template') apply_template('l3_leaf_node', service, template_vars) # Process border-leaf nodes border_leaf_nodes = root.plant_information.plant[ service.dc_name].border_leaf_node dci_vlans = [vlan for vlan in service.dci.vlan] if len(dci_vlans) % len(border_leaf_nodes) != 0: raise NcsServiceError( 'Number of DCI VLANs must be divisible by the number of border-leaf nodes' ) for b_leaf, b_leaf_dci_vlans in zip( border_leaf_nodes, split_l3_dci_vlans(dci_vlans, len(border_leaf_nodes))): if num_dci_ports(b_leaf.dci_layer3) != len(b_leaf_dci_vlans): raise NcsServiceError( 'Border-leaf number of L3 DCI ports does not match number of DCI VLANs.' ) b_leaf_info = service.border_leaf_info.create(b_leaf.name) fill_border_leaf_info(b_leaf_info, b_leaf.dci_layer3, b_leaf_dci_vlans) self.log.info('Rendering L3 border-leaf template') apply_template('l3_border_leaf_node', service, template_vars) return proplist
def cb_create(self, tctx, root, service, proplist, self_plan): template_vars = { 'NVE_SOURCE': root.plant_information.global_config.nve_source_interface, } # Process leaf nodes self.log.info('Rendering L2 leaf template') apply_template('l2_leaf_node', service, template_vars) # Process border-leaf nodes border_leaf_nodes = root.plant_information.plant[ service.dc_name].border_leaf_node dci_vlans = [vlan for vlan in service.dci.vlan] if not ((len(dci_vlans) == 1) or (len(dci_vlans) == len(border_leaf_nodes))): raise NcsServiceError( 'Number of L2 DCI VLANs must be either 1 or match the number of border-leaf nodes' ) for b_leaf, b_leaf_dci_vlans in zip(border_leaf_nodes, split_l2_dci_vlans(dci_vlans)): if num_dci_ports(b_leaf.dci_layer2) != 1: raise NcsServiceError( 'Each border-leaf can only have one L2 DCI port. ') b_leaf_info = service.border_leaf_info.create(b_leaf.name) fill_border_leaf_info(b_leaf_info, b_leaf.dci_layer2, b_leaf_dci_vlans) self.log.info('Rendering L2 border-leaf template') apply_template('l2_border_leaf_node', service, template_vars) return proplist