def vnc_port_delete(self, vmi_id, pod_id): self._unset_tags_on_pod_vmi(pod_id, vmi_id=vmi_id) vmi = VirtualMachineInterfaceKM.get(vmi_id) if not vmi: return for iip_id in list(vmi.instance_ips): try: self._vnc_lib.instance_ip_delete(id=iip_id) except NoIdError: pass # Cleanup floating ip's on this interface. for fip_id in list(vmi.floating_ips): try: self._vnc_lib.ref_update('floating-ip', fip_id, 'virtual-machine-interface', vmi_id, None, 'DELETE') FloatingIpKM.update(fip_id) except NoIdError: pass try: self._vnc_lib.virtual_machine_interface_delete(id=vmi_id) except NoIdError: pass VirtualMachineInterfaceKM.delete(vmi_id)
def _create_vmi(self, pod_name, pod_namespace, pod_id, vm_obj, vn_obj, parent_vmi, idx, network=None): proj_fq_name = vnc_kube_config.cluster_project_fq_name(pod_namespace) proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) if network and 'namespace' in network: network.pop('namespace') vmi_prop = None if self._is_pod_nested() and parent_vmi: # Pod is nested. # Allocate a vlan-id for this pod from the vlan space managed # in the VMI of the underlay VM. parent_vmi = VirtualMachineInterfaceKM.get(parent_vmi.uuid) vlan_id = parent_vmi.alloc_vlan() vmi_prop = VirtualMachineInterfacePropertiesType( sub_interface_vlan_tag=vlan_id) obj_uuid = str(uuid.uuid1()) name = VncCommon.make_name(pod_name, obj_uuid) vmi_obj = VirtualMachineInterface( name=name, parent_obj=proj_obj, virtual_machine_interface_properties=vmi_prop, display_name=name) vmi_obj.uuid = obj_uuid vmi_obj.set_virtual_network(vn_obj) vmi_obj.set_virtual_machine(vm_obj) self._associate_security_groups(vmi_obj, proj_obj, pod_namespace) vmi_obj.port_security_enabled = True VirtualMachineInterfaceKM.add_annotations(self, vmi_obj, pod_namespace, pod_name, index=idx, **network) try: vmi_uuid = self._vnc_lib.virtual_machine_interface_create(vmi_obj) except RefsExistError: vmi_uuid = self._vnc_lib.virtual_machine_interface_update(vmi_obj) VirtualMachineInterfaceKM.locate(vmi_uuid) return vmi_uuid
def _add_pod_to_service(self, service_id, pod_id, port=None): lb = LoadbalancerKM.get(service_id) if not lb: return vm = VirtualMachineKM.get(pod_id) if not vm: return for lb_listener_id in lb.loadbalancer_listeners: pool = self._get_loadbalancer_pool(lb_listener_id, port) if not pool: continue for vmi_id in vm.virtual_machine_interfaces: vmi = VirtualMachineInterfaceKM.get(vmi_id) if not vmi: continue for member_id in pool.members: member = LoadbalancerMemberKM.get(member_id) if member and member.vmi == vmi_id: break else: self.logger.debug( "Creating LB member for Pod/VM: %s in LB: %s with " "target-port: %d" % (vm.fq_name, lb.name, port['port'])) member_obj = self._vnc_create_member( pool, pod_id, vmi_id, port['port']) LoadbalancerMemberKM.locate(member_obj.uuid)
def _read_allocated_floating_ips(self, service_id): floating_ips = set() lb = LoadbalancerKM.get(service_id) if not lb: return vmi_ids = lb.virtual_machine_interfaces if vmi_ids is None: return None interface_found = False for vmi_id in vmi_ids: vmi = VirtualMachineInterfaceKM.get(vmi_id) if vmi is not None: interface_found = True break if not interface_found: return fip_ids = vmi.floating_ips if fip_ids is None: return None for fip_id in list(fip_ids): fip = FloatingIpKM.get(fip_id) if fip is not None: floating_ips.add(fip.address) return floating_ips
def _get_iip(self, vmi_uuid): vmi = self._vnc_lib.virtual_machine_interface_read(id=vmi_uuid) vmi = VirtualMachineInterfaceKM.locate(vmi_uuid) iip_uuid = list(vmi.instance_ips)[0] iip_obj = self._vnc_lib.instance_ip_read(id=iip_uuid) iip_ip = iip_obj.get_instance_ip_address() return iip_ip
def _update_network_status(self, pod_name, pod_namespace, network_status): net_status_dict_list = [] for nw_name, vmi_uuid in list(network_status.items()): vmi_obj = self._vnc_lib.virtual_machine_interface_read(id=vmi_uuid) vmi = VirtualMachineInterfaceKM.locate(vmi_uuid) pod_iips = [] for iip_uuid in list(vmi.instance_ips): iip_obj = self._vnc_lib.instance_ip_read(id=iip_uuid) if not iip_obj.get_instance_ip_secondary(): ip = iip_obj.get_instance_ip_address() pod_iips.append(ip) ns_dict = {} ns_dict['name'] = nw_name ns_dict['ips'] = ''.join(pod_iips) ns_dict['mac'] = \ ''.join(vmi_obj.get_virtual_machine_interface_mac_addresses().get_mac_address()) net_status_dict_list.append(ns_dict) patch = { 'metadata': { 'annotations': { 'k8s.v1.cni.cncf.io/network-status': json.dumps(net_status_dict_list, sort_keys=True, indent=4, separators=(',', ': ')) } } } if self._kube is not None: self._kube.patch_resource("pod", pod_name, patch, pod_namespace)
def _update_network_status(self, pod_name, pod_namespace, network_status): net_status_dict_list = [] for nw_name,vmi_uuid in network_status.items(): vmi_obj = self._vnc_lib.virtual_machine_interface_read(id=vmi_uuid) vmi = VirtualMachineInterfaceKM.locate(vmi_uuid) pod_iips = [] for iip_uuid in list(vmi.instance_ips): iip_obj = self._vnc_lib.instance_ip_read(id=iip_uuid) if not iip_obj.get_instance_ip_secondary(): ip = iip_obj.get_instance_ip_address() pod_iips.append(ip) ns_dict = {} ns_dict['name'] = nw_name ns_dict['ips'] = ''.join(pod_iips) ns_dict['mac'] = \ ''.join(vmi_obj.get_virtual_machine_interface_mac_addresses(\ ).get_mac_address()) net_status_dict_list.append(ns_dict) patch = {'metadata': {'annotations': {\ 'k8s.v1.cni.cncf.io/network-status':\ json.dumps(net_status_dict_list)}}} if self._kube is not None: self._kube.patch_resource("pods", pod_name, patch, \ pod_namespace, beta=False)
def _delete_virtual_interface(self, vmi_ids): for vmi_id in vmi_ids: vmi = VirtualMachineInterfaceKM.get(vmi_id) if vmi: # Delete vmi-->floating-ip fip_ids = vmi.floating_ips.copy() for fip_id in fip_ids: try: self._vnc_lib.floating_ip_delete(id=fip_id) except NoIdError: # already deleted and not updated in the local-cache continue ip_ids = vmi.instance_ips.copy() for ip_id in ip_ids: ip = InstanceIpKM.get(ip_id) if ip: fip_ids = ip.floating_ips.copy() for fip_id in fip_ids: # Delete vmi-->instance-ip-->floating-ip try: self._vnc_lib.floating_ip_delete(id=fip_id) except NoIdError: # deleted by svc-monitor pass # Delete vmi-->instance-ip self._vnc_lib.instance_ip_delete(id=ip_id) # Delete vmi self.logger.debug("Deleting LB Interface %s" % vmi.name) self._vnc_lib.virtual_machine_interface_delete(id=vmi_id)
def vnc_pod_add(self, pod_id, pod_name, pod_namespace, pod_node, node_ip, labels, vm_vmi): vm = VirtualMachineKM.get(pod_id) if vm: vm.pod_namespace = pod_namespace if not vm.virtual_router: self._link_vm_to_node(vm, pod_node, node_ip) self._set_label_to_pod_cache(labels, vm) return vm else: self._check_pod_uuid_change(pod_id, pod_name) vn_obj = self._get_network(pod_id, pod_name, pod_namespace) if not vn_obj: return vm_obj = self._create_vm(pod_namespace, pod_id, pod_name, labels) vmi_uuid = self._create_vmi(pod_name, pod_namespace, vm_obj, vn_obj, vm_vmi) vmi = VirtualMachineInterfaceKM.get(vmi_uuid) if self._is_pod_nested() and vm_vmi: # Pod is nested. # Link the pod VMI to the VMI of the underlay VM. self._vnc_lib.ref_update('virtual-machine-interface', vm_vmi.uuid, 'virtual-machine-interface', vmi_uuid, None, 'ADD') self._vnc_lib.ref_update('virtual-machine-interface', vmi_uuid, 'virtual-machine-interface', vm_vmi.uuid, None, 'ADD') # get host id for vm vmi vr_uuid = None for vr in VirtualRouterKM.values(): if vr.name == vm_vmi.host_id: vr_uuid = vr.uuid break if not vr_uuid: self._logger.error( "No virtual-router object found for host: " + vm_vmi.host_id + ". Unable to add VM reference to a" + " valid virtual-router") return self._vnc_lib.ref_update('virtual-router', vr_uuid, 'virtual-machine', vm_obj.uuid, None, 'ADD') self._create_iip(pod_name, pod_namespace, vn_obj, vmi) if not self._is_pod_nested(): self._link_vm_to_node(vm_obj, pod_node, node_ip) vm = VirtualMachineKM.locate(pod_id) if vm: vm.pod_namespace = pod_namespace vm.pod_node = pod_node vm.node_ip = node_ip self._set_label_to_pod_cache(labels, vm) return vm
def _add_pod_to_service(self, service_id, pod_id, port=None, address=None): lb = LoadbalancerKM.get(service_id) if not lb: return vm = VirtualMachineKM.get(pod_id) host_vmi = None if not vm: if not self._args.host_network_service: return host_vmi = self._get_vmi_from_ip(address) if host_vmi == None: return else: vm = VirtualMachine(name="host", display_name="host") vm.virtual_machine_interfaces = [host_vmi] for lb_listener_id in lb.loadbalancer_listeners: pool = self._get_loadbalancer_pool(lb_listener_id, port) if not pool: continue for vmi_id in vm.virtual_machine_interfaces: if host_vmi == None: vmi = VirtualMachineInterfaceKM.get(vmi_id) else: vmi = self._vnc_lib.virtual_machine_interface_read( id=vmi_id) if not vmi: continue for member_id in pool.members: member = LoadbalancerMemberKM.get(member_id) if member and member.vmi == vmi_id: break else: self.logger.debug( "Creating LB member for Pod/VM: %s in LB: %s with " "target-port: %d" % (vm.fq_name, lb.name, port['port'])) member_obj = self._vnc_create_member( pool, pod_id, vmi_id, port['port']) try: vmi_obj = self._vnc_lib.virtual_machine_interface_read( id=vmi_id) except: raise # Attach the service label to underlying pod vmi. self._labels.append( vmi_id, self._labels.get_service_label(lb.service_name)) # Set tags on the vmi. self._vnc_lib.set_tags( vmi_obj, self._labels.get_labels_dict(vmi_id)) LoadbalancerMemberKM.locate(member_obj.uuid)
def vnc_pod_vmi_create(self, pod_id, pod_name, pod_namespace, pod_node, node_ip, vm_obj, vn_obj, vm_vmi, idx, nw_name=''): vmi_uuid = self._create_vmi(pod_name, pod_namespace, pod_id, vm_obj, vn_obj, vm_vmi, idx, nw_name) vmi = VirtualMachineInterfaceKM.get(vmi_uuid) if self._is_pod_nested() and vm_vmi: # Pod is nested. # Link the pod VMI to the VMI of the underlay VM. self._vnc_lib.ref_update('virtual-machine-interface', vm_vmi.uuid, 'virtual-machine-interface', vmi_uuid, None, 'ADD') self._vnc_lib.ref_update('virtual-machine-interface', vmi_uuid, 'virtual-machine-interface', vm_vmi.uuid, None, 'ADD') # get host id for vm vmi vr_uuid = None for vr in VirtualRouterKM.values(): if vr.name == vm_vmi.host_id: vr_uuid = vr.uuid break if not vr_uuid: # Unable to determine VRouter for the parent VM. # # HACK ALERT # # It is possible that this is a case of FQDN mismatch between # the host name associated with the VM and the host name # associated with the corresponding vrouter. So try to look for # vrouter again with a non-FQDN name. # # This needs to be removed when provisioning can guarantee that # FQDN will be uniform across all config objects. # if '.' in vm_vmi.host_id: # Host name on VM is a FQNAME. Ignore domain name. host_id_prefix = vm_vmi.host_id.split('.')[0] for vr in VirtualRouterKM.values(): if vr.name == host_id_prefix: vr_uuid = vr.uuid break if not vr_uuid: self._logger.error("No virtual-router object found for host: " + vm_vmi.host_id + ". Unable to add VM reference to a" + " valid virtual-router") return self._vnc_lib.ref_update('virtual-router', vr_uuid, 'virtual-machine', vm_obj.uuid, None, 'ADD') iip_obj = self._create_iip(pod_name, pod_namespace, vn_obj, vmi) return vmi_uuid
def _get_host_vm(host_ip): iip = InstanceIpKM.get_object( host_ip, vnc_kube_config.cluster_default_network_fq_name()) if iip: for vmi_id in iip.virtual_machine_interfaces: vm_vmi = VirtualMachineInterfaceKM.get(vmi_id) if vm_vmi and vm_vmi.virtual_machine: return vm_vmi.virtual_machine return None
def create_virtual_machine(self, name, vn, ipaddress): vm = VirtualMachine(name) self._vnc_lib.virtual_machine_create(vm) VirtualMachineKM.locate(vm.uuid) vmi = VirtualMachineInterface( parent_type='virtual-machine', fq_name=[name, '0']) vmi.set_virtual_machine(vm) vmi.set_virtual_network(vn) self._vnc_lib.virtual_machine_interface_create(vmi) VirtualMachineInterfaceKM.locate(vmi.uuid) ip = InstanceIp(vm.name + '.0') ip.set_virtual_machine_interface(vmi) ip.set_virtual_network(vn) ip.set_instance_ip_address(ipaddress) self._vnc_lib.instance_ip_create(ip) InstanceIpKM.locate(ip.uuid) return vm, vmi, ip
def _get_host_vmi(self, pod_name): host_ip = self._get_host_ip(pod_name) if host_ip: net_fq_name = vnc_kube_config.cluster_default_network_fq_name() iip = InstanceIpKM.get_object(host_ip, net_fq_name) if iip: for vmi_id in iip.virtual_machine_interfaces: vm_vmi = VirtualMachineInterfaceKM.get(vmi_id) if vm_vmi and vm_vmi.host_id: return vm_vmi return None
def create_virtual_machine(self, name, vn, ipaddress): vm = VirtualMachine(name) self._vnc_lib.virtual_machine_create(vm) VirtualMachineKM.locate(vm.uuid) vmi = VirtualMachineInterface( parent_type='virtual-machine', fq_name=[name, '0']) vmi.set_virtual_machine(vm) vmi.set_virtual_network(vn) if DBBaseKM.is_nested(): vmi.set_virtual_machine_interface_bindings( KeyValuePairs([KeyValuePair('host_id', 'WHATEVER')])) self._vnc_lib.virtual_machine_interface_create(vmi) VirtualMachineInterfaceKM.locate(vmi.uuid) ip = InstanceIp(vm.name + '.0') ip.set_virtual_machine_interface(vmi) ip.set_virtual_network(vn) ip.set_instance_ip_address(ipaddress) self._vnc_lib.instance_ip_create(ip) InstanceIpKM.locate(ip.uuid) return vm, vmi, ip
def _deallocate_floating_ip(self, lb): vmi_id = list(lb.virtual_machine_interfaces)[0] vmi = VirtualMachineInterfaceKM.get(vmi_id) if vmi is None: self._logger.error("%s - %s Vmi %s Not Found" % (self._name, lb.name, vmi_id)) return fip_list = vmi.floating_ips.copy() for fip_id in fip_list or []: fip_obj = self._vnc_lib.floating_ip_read(id=fip_id) fip_obj.set_virtual_machine_interface_list([]) self._vnc_lib.floating_ip_update(fip_obj) self._vnc_lib.floating_ip_delete(id=fip_obj.uuid) FloatingIpKM.delete(fip_obj.uuid)
def create_virtual_machine(self, name, vn, ipaddress): vm = VirtualMachine(name) self._vnc_lib.virtual_machine_create(vm) VirtualMachineKM.locate(vm.uuid) vmi = VirtualMachineInterface(parent_type='virtual-machine', fq_name=[name, '0']) vmi.set_virtual_machine(vm) vmi.set_virtual_network(vn) if DBBaseKM.is_nested(): vmi.set_virtual_machine_interface_bindings( KeyValuePairs([KeyValuePair('host_id', 'WHATEVER')])) self._vnc_lib.virtual_machine_interface_create(vmi) VirtualMachineInterfaceKM.locate(vmi.uuid) ip = InstanceIp(vm.name + '.0') ip.set_virtual_machine_interface(vmi) ip.set_virtual_network(vn) ip.set_instance_ip_address(ipaddress) self._vnc_lib.instance_ip_create(ip) InstanceIpKM.locate(ip.uuid) return vm, vmi, ip
def _create_vmi(self, pod_name, pod_namespace, pod_id, vm_obj, vn_obj, parent_vmi, idx, nw_name=''): proj_fq_name = vnc_kube_config.cluster_project_fq_name(pod_namespace) proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) vmi_prop = None if self._is_pod_nested() and parent_vmi: # Pod is nested. # Allocate a vlan-id for this pod from the vlan space managed # in the VMI of the underlay VM. parent_vmi = VirtualMachineInterfaceKM.get(parent_vmi.uuid) vlan_id = parent_vmi.alloc_vlan() vmi_prop = VirtualMachineInterfacePropertiesType( sub_interface_vlan_tag=vlan_id) obj_uuid = str(uuid.uuid1()) name = VncCommon.make_name(pod_name, obj_uuid) vmi_obj = VirtualMachineInterface( name=name, parent_obj=proj_obj, virtual_machine_interface_properties=vmi_prop, display_name=name) vmi_obj.uuid = obj_uuid vmi_obj.set_virtual_network(vn_obj) vmi_obj.set_virtual_machine(vm_obj) self._associate_security_groups(vmi_obj, proj_obj, pod_namespace) vmi_obj.port_security_enabled = True VirtualMachineInterfaceKM.add_annotations(self, vmi_obj, pod_namespace, pod_name, index=idx, network=nw_name) try: vmi_uuid = self._vnc_lib.virtual_machine_interface_create(vmi_obj) except RefsExistError: vmi_uuid = self._vnc_lib.virtual_machine_interface_update(vmi_obj) VirtualMachineInterfaceKM.locate(vmi_uuid) return vmi_uuid
def _update_sg_pod_link(self, namespace, pod_id, sg_id, oper, validate_vm=True, validate_sg=False): vm = VirtualMachineKM.get(pod_id) if not vm or vm.owner != 'k8s': return if validate_vm and vm.pod_namespace != namespace: return if validate_sg: sg = SecurityGroupKM.get(sg_id) if not sg or sg.namespace != namespace: return match_found = False sg_labels = sg.np_pod_selector.copy() sg_labels.update(sg.ingress_pod_selector) if set(sg_labels.items()).issubset(set(vm.pod_labels.items())): match_found = True if oper == 'ADD' and not match_found: return elif oper == 'DELETE' and match_found: return for vmi_id in vm.virtual_machine_interfaces: vmi = VirtualMachineInterfaceKM.get(vmi_id) if not vmi: return try: self._logger.debug("%s - %s SG-%s Ref for Pod-%s" % (self._name, oper, sg_id, pod_id)) self._vnc_lib.ref_update('virtual-machine-interface', vmi_id, 'security-group', sg_id, None, oper) except RefsExistError: self._logger.error("%s - SG-%s Ref Exists for pod-%s" % (self._name, sg_id, pod_id)) except Exception: self._logger.error("%s - Failed to %s SG-%s Ref for pod-%s" % (self._name, oper, sg_id, pod_id))
def vnc_port_delete(self, vmi_id): vmi = VirtualMachineInterfaceKM.get(vmi_id) if not vmi: return for iip_id in list(vmi.instance_ips): try: self._vnc_lib.instance_ip_delete(id=iip_id) except NoIdError: pass # Cleanup floating ip's on this interface. for fip_id in list(vmi.floating_ips): try: self._vnc_lib.floating_ip_delete(id=fip_id) except NoIdError: pass try: self._vnc_lib.virtual_machine_interface_delete(id=vmi_id) except NoIdError: pass
def update_pod_np(self, pod_namespace, pod_id, labels): vm = VirtualMachineKM.get(pod_id) if not vm or vm.owner != 'k8s': return namespace_label = self._label_cache._get_namespace_label(pod_namespace) labels.update(namespace_label) np_sg_uuid_set = self._find_sg(self._np_pod_label_cache, labels) ingress_sg_uuid_set = self._find_sg(self._ingress_pod_label_cache, labels) new_sg_uuid_set = np_sg_uuid_set | ingress_sg_uuid_set vmi_sg_uuid_set = set() for vmi_id in vm.virtual_machine_interfaces: vmi = VirtualMachineInterfaceKM.get(vmi_id) if not vmi: continue vmi_sg_uuid_set = vmi.security_groups default_ns_sgs = set() for sg_name in list( self._default_ns_sgs[pod_namespace].keys()) or []: sg_uuid = self._default_ns_sgs[pod_namespace][sg_name] default_ns_sgs.add(sg_uuid) vmi_sg_uuid_set = vmi_sg_uuid_set - default_ns_sgs old_sg_uuid_set = vmi_sg_uuid_set removed_sg_uuid_set = old_sg_uuid_set for sg_uuid in removed_sg_uuid_set or []: self._update_sg_pod_link(pod_namespace, pod_id, sg_uuid, 'DELETE', validate_sg=True) added_sg_uuid_set = new_sg_uuid_set - old_sg_uuid_set for sg_uuid in added_sg_uuid_set or []: self._update_sg_pod_link(pod_namespace, pod_id, sg_uuid, 'ADD', validate_sg=True)
def _deallocate_floating_ips(self, service_id): lb = LoadbalancerKM.get(service_id) if not lb: return vmi_ids = lb.virtual_machine_interfaces if vmi_ids is None: return None interface_found = False for vmi_id in vmi_ids: vmi = VirtualMachineInterfaceKM.get(vmi_id) if vmi is not None: interface_found = True break if interface_found is False: return fip_ids = vmi.floating_ips.copy() for fip_id in fip_ids: try: self._vnc_lib.floating_ip_delete(id=fip_id) except NoIdError: pass
def _assert_virtual_machine(self, pod_uuid, cluster_project, proj_obj, vn_obj_uuid): vm = self._vnc_lib.virtual_machine_read(id=pod_uuid) self.assertIsNotNone(vm) vm = VirtualMachineKM.locate(vm.uuid) self.assertIsNotNone(vm) self.assertTrue(len(vm.virtual_machine_interfaces) > 0) for vmi_id in list(vm.virtual_machine_interfaces): vmi = self._vnc_lib.virtual_machine_interface_read(id=vmi_id) self.assertIsNotNone(vmi) self.assertEqual(vmi.parent_name, cluster_project) self.assertEqual(vmi.parent_uuid, proj_obj.uuid) vmi = VirtualMachineInterfaceKM.locate(vmi_id) self.assertTrue(len(vmi.security_groups) > 1) for sg_uuid in list(vmi.security_groups): sg = self._vnc_lib.security_group_read(id=sg_uuid) self.assertIsNotNone(sg) self.assertTrue(len(vmi.instance_ips) == 1) iip_uuid = list(vmi.instance_ips)[0] iip = self._vnc_lib.instance_ip_read(id=iip_uuid) self.assertIsNotNone(iip) self._assert_pod_ip_is_from_vn_ipam(iip, vn_obj_uuid)
def _assert_virtual_machine(self, pod_uuid, cluster_project, proj_obj, vn_obj_uuid): vm = self._vnc_lib.virtual_machine_read(id=pod_uuid) self.assertIsNotNone(vm) vm = VirtualMachineKM.locate(vm.uuid) self.assertIsNotNone(vm) self.assertTrue(len(vm.virtual_machine_interfaces) > 0) for vmi_id in list(vm.virtual_machine_interfaces): vmi = self._vnc_lib.virtual_machine_interface_read(id=vmi_id) self.assertIsNotNone(vmi) self.assertEqual(vmi.parent_name, cluster_project) self.assertEqual(vmi.parent_uuid, proj_obj.uuid) vmi = VirtualMachineInterfaceKM.locate(vmi_id) # self.assertTrue(len(vmi.security_groups) > 1) # for sg_uuid in list(vmi.security_groups): # sg = self._vnc_lib.security_group_read(id=sg_uuid) # self.assertIsNotNone(sg) self.assertTrue(len(vmi.instance_ips) == 1) iip_uuid = list(vmi.instance_ips)[0] iip = self._vnc_lib.instance_ip_read(id=iip_uuid) self.assertIsNotNone(iip) self._assert_pod_ip_is_from_vn_ipam(iip, vn_obj_uuid)
def vnc_pod_add(self, pod_id, pod_name, pod_namespace, pod_node, node_ip, labels, vm_vmi): vm = VirtualMachineKM.get(pod_id) if vm: vm.pod_namespace = pod_namespace if not vm.virtual_router: self._link_vm_to_node(vm, pod_node, node_ip) self._set_label_to_pod_cache(labels, vm) return vm else: self._check_pod_uuid_change(pod_id, pod_name) vn_obj = self._get_network(pod_id, pod_name, pod_namespace) if not vn_obj: return vm_obj = self._create_vm(pod_namespace, pod_id, pod_name, labels) vmi_uuid = self._create_vmi(pod_name, pod_namespace, vm_obj, vn_obj, vm_vmi) vmi = VirtualMachineInterfaceKM.get(vmi_uuid) if self._is_pod_nested() and vm_vmi: # Pod is nested. # Link the pod VMI to the VMI of the underlay VM. self._vnc_lib.ref_update('virtual-machine-interface', vm_vmi.uuid, 'virtual-machine-interface', vmi_uuid, None, 'ADD') self._vnc_lib.ref_update('virtual-machine-interface', vmi_uuid, 'virtual-machine-interface', vm_vmi.uuid, None, 'ADD') # get host id for vm vmi vr_uuid = None for vr in VirtualRouterKM.values(): if vr.name == vm_vmi.host_id: vr_uuid = vr.uuid break if not vr_uuid: self._logger.error("No virtual-router object found for host: " + vm_vmi.host_id + ". Unable to add VM reference to a" + " valid virtual-router") return self._vnc_lib.ref_update('virtual-router', vr_uuid, 'virtual-machine', vm_obj.uuid, None, 'ADD') self._create_iip(pod_name, pod_namespace, vn_obj, vmi) if self._is_pod_network_isolated(pod_namespace): self._create_cluster_service_fip(pod_name, pod_namespace, vmi_uuid) if not self._is_pod_nested(): self._link_vm_to_node(vm_obj, pod_node, node_ip) vm = VirtualMachineKM.locate(pod_id) if vm: vm.pod_namespace = pod_namespace vm.pod_node = pod_node vm.node_ip = node_ip self._set_label_to_pod_cache(labels, vm) return vm
def _allocate_floating_ips(self, service_id, specified_fip_pool_fq_name_str, service_namespace, external_ips=set()): lb = LoadbalancerKM.get(service_id) if not lb: return None vmi_ids = lb.virtual_machine_interfaces if vmi_ids is None: return None interface_found = False for vmi_id in vmi_ids: vmi = VirtualMachineInterfaceKM.get(vmi_id) if vmi is not None: interface_found = True break if not interface_found: return vmi_obj = self._vnc_lib.virtual_machine_interface_read(id=vmi_id) if vmi_obj is None: return None fip_pool = None if specified_fip_pool_fq_name_str is not None: fip_pool = self._get_specified_fip_pool( specified_fip_pool_fq_name_str) if fip_pool is None and self._get_annotated_ns_fip_pool( service_namespace) is not None: fip_pool = self._get_annotated_ns_fip_pool(service_namespace) if fip_pool is None: fip_pool = self._get_public_fip_pool() if fip_pool is None: self.logger.warning("public_fip_pool doesn't exists") return None def _check_ip_with_fip_pool(external_ip, fip_pool_obj): try: vn_obj = self._vnc_lib.virtual_network_read( id=fip_pool_obj.parent_uuid) except NoIdError: return True ipam_refs = vn_obj.__dict__.get('network_ipam_refs', []) for ipam_ref in ipam_refs: vnsn_data = ipam_ref['attr'].__dict__ ipam_subnets = vnsn_data.get('ipam_subnets', []) for ipam_subnet in ipam_subnets: subnet_dict = ipam_subnet.__dict__.get('subnet', {}) if 'ip_prefix' in subnet_dict.__dict__: ip_subnet_str = ( subnet_dict.__dict__.get('ip_prefix', '') + '/' + str(subnet_dict.__dict__.get('ip_prefix_len'))) if IPAddress(external_ip) in IPNetwork(ip_subnet_str): return True self.logger.error("external_ip not in fip_pool subnet") return False def _allocate_floating_ip(lb, vmi, fip_pool, external_ip=None): fip_obj = FloatingIp(lb.name + str(external_ip) + "-externalIP", fip_pool) fip_obj.set_virtual_machine_interface(vmi_obj) if external_ip: if not (_check_ip_with_fip_pool(external_ip, fip_pool)): err_str = "external_ip " + external_ip + " not in fip_pool subnet" self.logger.error(err_str) return None fip_obj.set_floating_ip_address(external_ip) project = self._vnc_lib.project_read(id=lb.parent_uuid) fip_obj.set_project(project) try: self._vnc_lib.floating_ip_create(fip_obj) except RefsExistError: string_buf = StringIO() cgitb_hook(file=string_buf, format="text") err_msg = string_buf.getvalue() self.logger.error("%s" % (err_msg)) except Exception: string_buf = StringIO() cgitb_hook(file=string_buf, format="text") err_msg = string_buf.getvalue() self.logger.error("%s" % (err_msg)) fip = FloatingIpKM.locate(fip_obj.uuid) self.logger.notice("floating ip allocated : %s for Service (%s)" % (fip.address, service_id)) return (fip.address) fips = set() if len(external_ips) == 0: fip_addr = _allocate_floating_ip(lb, vmi, fip_pool) if fip_addr: fips.add(fip_addr) return fips for external_ip in external_ips: fip_addr = _allocate_floating_ip(lb, vmi, fip_pool, external_ip) if fip_addr: fips.add(fip_addr) return fips
def _add_pod_to_service(self, service_id, pod_id, port=None, address=None): lb = LoadbalancerKM.get(service_id) if not lb: return vm = VirtualMachineKM.get(pod_id) host_vmi = None if not vm: if not self._args.host_network_service: return host_vmi = self._get_vmi_from_ip(address) if host_vmi == None: return else: vm = VirtualMachine(name="host", display_name="host") vm.virtual_machine_interfaces = [host_vmi] for lb_listener_id in lb.loadbalancer_listeners: pool = self._get_loadbalancer_pool(lb_listener_id, port) if not pool: continue for vmi_id in vm.virtual_machine_interfaces: if host_vmi == None: vmi = VirtualMachineInterfaceKM.get(vmi_id) else: vmi = self._vnc_lib.virtual_machine_interface_read(id=vmi_id) if not vmi: continue # Add VMI only if it matches the default address for endpoint, # ignore other interfaces for pod ip_found = False for iip_uuid in vmi.instance_ips: iip = InstanceIpKM.get(iip_uuid) if iip and iip.address == address: ip_found = True break if ip_found == False: continue for member_id in pool.members: member = LoadbalancerMemberKM.get(member_id) if member and member.vmi == vmi_id: break else: self.logger.debug( "Creating LB member for Pod/VM: %s in LB: %s with " "target-port: %d" % (vm.fq_name, lb.name, port['port'])) member_obj = self._vnc_create_member( pool, pod_id, vmi_id, port['port']) try: vmi_obj = self._vnc_lib.virtual_machine_interface_read( id = vmi_id) except: raise # Attach the service label to underlying pod vmi. self._labels.append(vmi_id, self._labels.get_service_label(lb.service_name)) # Set tags on the vmi. self._vnc_lib.set_tags(vmi_obj, self._labels.get_labels_dict(vmi_id)) LoadbalancerMemberKM.locate(member_obj.uuid)
def _create_virtual_interface(self, proj_obj, vn_obj, service_ns, service_name, service_id, k8s_event_type, vip_address=None, subnet_uuid=None, tags=None): vmi_uuid = str(uuid.uuid4()) cluster_name = vnc_kube_config.cluster_name() vmi_name = VncCommon.make_name(cluster_name, k8s_event_type, service_name, service_id) vmi_display_name = VncCommon.make_display_name(service_ns, service_name) # Check if VMI exists, if yes, delete it. vmi_obj = VirtualMachineInterface(name=vmi_name, parent_obj=proj_obj, display_name=vmi_display_name) try: vmi_id = self._vnc_lib.fq_name_to_id('virtual-machine-interface', vmi_obj.get_fq_name()) if vmi_id: self.logger.error("Duplicate LB Interface %s, delete it" % vmi_obj.get_fq_name()) vmi = VirtualMachineInterfaceKM.get(vmi_id) iip_ids = vmi.instance_ips for iip_id in list(iip_ids): iip_obj = self._vnc_lib.instance_ip_read(id=iip_id) fip_refs = iip_obj.get_floating_ips() for fip_ref in fip_refs or []: fip = self._vnc_lib.floating_ip_read( id=fip_ref['uuid']) fip.set_virtual_machine_interface_list([]) self._vnc_lib.floating_ip_update(fip) self._vnc_lib.floating_ip_delete(id=fip_ref['uuid']) self._vnc_lib.instance_ip_delete(id=iip_obj.uuid) self._vnc_lib.virtual_machine_interface_delete(id=vmi_id) except NoIdError: pass # Create LB VMI vmi_obj.name = vmi_name vmi_obj.uuid = vmi_uuid vmi_obj.set_virtual_network(vn_obj) vmi_obj.set_virtual_machine_interface_device_owner("K8S:LOADBALANCER") sg_name = "-".join( [vnc_kube_config.cluster_name(), service_ns, 'default-sg']) sg_obj = SecurityGroup(sg_name, proj_obj) vmi_obj.add_security_group(sg_obj) vmi_obj.port_security_enabled = True try: self.logger.debug("Create LB Interface %s " % vmi_obj.get_fq_name()) self._vnc_lib.virtual_machine_interface_create(vmi_obj) VirtualMachineInterfaceKM.locate(vmi_obj.uuid) except BadRequest as e: self.logger.warning("LB (%s) Interface create failed %s " % (service_name, str(e))) return None, None try: vmi_obj = self._vnc_lib.virtual_machine_interface_read( id=vmi_obj.uuid) except NoIdError: self.logger.warning("Read Service VMI failed for" " service (" + service_name + ")" + " with NoIdError for vmi(" + vmi_id + ")") return None, None # Attach tags on this VMI. if tags: self._vnc_lib.set_tags(vmi_obj, tags) # Create InstanceIP <--- LB VMI iip_uuid = str(uuid.uuid4()) iip_name = VncCommon.make_name(service_name, iip_uuid) iip_display_name = VncCommon.make_display_name(service_ns, service_name) perms2 = PermType2() perms2.owner = proj_obj.uuid perms2.owner_access = cfgm_common.PERMS_RWX iip_obj = InstanceIp(name=iip_name, perms2=perms2, display_name=iip_display_name) iip_obj.uuid = iip_uuid iip_obj.set_virtual_network(vn_obj) if subnet_uuid: iip_obj.set_subnet_uuid(subnet_uuid) iip_obj.set_virtual_machine_interface(vmi_obj) iip_obj.set_display_name(service_name) if vip_address: iip_obj.set_instance_ip_address(vip_address) try: self.logger.debug("Create LB VMI InstanceIp %s " % iip_obj.get_fq_name()) self._vnc_lib.instance_ip_create(iip_obj) except RefsExistError: self._vnc_lib.instance_ip_update(iip_obj) InstanceIpKM.locate(iip_obj.uuid) iip_obj = self._vnc_lib.instance_ip_read(id=iip_obj.uuid) vip_address = iip_obj.get_instance_ip_address() self.logger.debug("Created LB VMI InstanceIp %s with VIP %s" % (iip_obj.get_fq_name(), vip_address)) return vmi_obj, vip_address
def _add_pod_to_service(self, service_id, pod_id, port=None, address=None): lb = LoadbalancerKM.get(service_id) if not lb: return vm = VirtualMachineKM.get(pod_id) host_vmi = None if not vm: if not self._args.host_network_service: return host_vmi = self._get_vmi_from_ip(address) if host_vmi is None: return else: vm = VirtualMachine(name="host", display_name="host") vm.virtual_machine_interfaces = [host_vmi] for lb_listener_id in lb.loadbalancer_listeners: pool = self._get_loadbalancer_pool(lb_listener_id, port) if not pool: continue for vmi_id in vm.virtual_machine_interfaces: vmi = VirtualMachineInterfaceKM.get(vmi_id) if not vmi: continue if host_vmi is None: # Add VMI only if it matches the default address for endpoint, # ignore other interfaces for pod ip_found = False for iip_uuid in vmi.instance_ips: iip = InstanceIpKM.get(iip_uuid) if iip and iip.address == address: ip_found = True break if not ip_found: continue for member_id in pool.members: member = LoadbalancerMemberKM.get(member_id) if member and member.vmi == vmi_id: break else: self.logger.debug( "Creating LB member for Pod/VM: %s in LB: %s with " "target-port: %d" % (vm.fq_name, lb.name, port['port'])) member_obj = self._vnc_create_member( pool, pod_id, vmi_id, port['port']) vmi_obj = self._vnc_lib.virtual_machine_interface_read( id=vmi_id) # Attach the service label to underlying pod vmi. self._labels.append( vmi_id, self._labels.get_service_label(lb.service_name)) # Set tags on the vmi. self._vnc_lib.set_tags( vmi_obj, self._labels.get_labels_dict(vmi_id)) LoadbalancerMemberKM.locate(member_obj.uuid)