def vnc_namespace_delete(self, namespace_id, name): proj_fq_name = vnc_kube_config.cluster_project_fq_name(name) project_uuid = ProjectKM.get_fq_name_to_uuid(proj_fq_name) if not project_uuid: self._logger.error("Unable to locate project for k8s namespace " "[%s]" % (name)) return project = ProjectKM.get(project_uuid) if not project: self._logger.error("Unable to locate project for k8s namespace " "[%s]" % (name)) return try: # If the namespace is isolated, delete its virtual network. if self._is_namespace_isolated(name): self._delete_policy(name, proj_fq_name) vn_name = self._get_namespace_pod_vn_name(name) self._delete_isolated_ns_virtual_network( name, vn_name=vn_name, proj_fq_name=proj_fq_name) # Clear pod network info from namespace entry. self._set_namespace_pod_virtual_network(name, None) vn_name = self._get_namespace_service_vn_name(name) self._delete_isolated_ns_virtual_network( name, vn_name=vn_name, proj_fq_name=proj_fq_name) # Clear service network info from namespace entry. self._set_namespace_service_virtual_network(name, None) # delete security groups security_groups = project.get_security_groups() for sg_uuid in security_groups: sg = SecurityGroupKM.get(sg_uuid) if not sg: continue sg_name = vnc_kube_config.get_default_sg_name(name) if sg.name != sg_name: continue for vmi_id in list(sg.virtual_machine_interfaces): try: self._vnc_lib.ref_update('virtual-machine-interface', vmi_id, 'security-group', sg.uuid, None, 'DELETE') except NoIdError: pass self._vnc_lib.security_group_delete(id=sg_uuid) # delete the label cache if project: self._clear_namespace_label_cache(namespace_id, project) # delete the namespace self._delete_namespace(name) # If project was created for this namesspace, delete the project. if vnc_kube_config.get_project_name_for_namespace(name) ==\ project.name: self._vnc_lib.project_delete(fq_name=proj_fq_name) except: # Raise it up to be logged. raise
def _associate_security_groups(vmi_obj, proj_obj, ns): sg_name = "-".join([vnc_kube_config.cluster_name(), ns, 'default']) sg_obj = SecurityGroup(sg_name, proj_obj) vmi_obj.add_security_group(sg_obj) ns_sg_name = "-".join([vnc_kube_config.cluster_name(), ns, 'sg']) sg_obj = SecurityGroup(ns_sg_name, proj_obj) vmi_obj.add_security_group(sg_obj) return
def _make_vn_fq_name(self, ns_name, vn_name, domain_name='default-domain'): vn_fq_name = [] vn_fq_name.append(domain_name) project_name = vnc_kube_config.cluster_project_name(ns_name) vn_fq_name.append(project_name) virtual_net_name = vnc_kube_config.get_pod_network_name(vn_name) vn_fq_name.append(virtual_net_name) return vn_fq_name
def __init__(self): self._k8s_event_type = 'Network' super(VncNetwork, self).__init__(self._k8s_event_type) self._name = type(self).__name__ self._vnc_lib = vnc_kube_config.vnc_lib() self._args = vnc_kube_config.args() self._logger = vnc_kube_config.logger() self._queue = vnc_kube_config.queue() self.ip_fabric_snat = False self.ip_fabric_forwarding = False
def __init__(self, network_policy_mgr): self._k8s_event_type = 'Namespace' super(VncNamespace, self).__init__(self._k8s_event_type) self._name = type(self).__name__ self._network_policy_mgr = network_policy_mgr self._vnc_lib = vnc_kube_config.vnc_lib() self._ns_sg = {} self._label_cache = vnc_kube_config.label_cache() self._logger = vnc_kube_config.logger() self._queue = vnc_kube_config.queue()
def __init__(self): super(VncEndpoints, self).__init__('Endpoint') self._name = type(self).__name__ self._vnc_lib = vnc_kube_config.vnc_lib() self.logger = vnc_kube_config.logger() self._kube = vnc_kube_config.kube() self.service_lb_pool_mgr = importutils.import_object( 'kube_manager.vnc.loadbalancer.ServiceLbPoolManager') self.service_lb_member_mgr = importutils.import_object( 'kube_manager.vnc.loadbalancer.ServiceLbMemberManager')
def vnc_namespace_delete(self, namespace_id, name): proj_fq_name = vnc_kube_config.cluster_project_fq_name(name) project_uuid = ProjectKM.get_fq_name_to_uuid(proj_fq_name) if not project_uuid: self._logger.error("Unable to locate project for k8s namespace " "[%s]" % (name)) return project = ProjectKM.get(project_uuid) if not project: self._logger.error("Unable to locate project for k8s namespace " "[%s]" % (name)) return default_sg_fq_name = proj_fq_name[:] sg = "-".join([vnc_kube_config.cluster_name(), name, 'default']) default_sg_fq_name.append(sg) ns_sg_fq_name = proj_fq_name[:] ns_sg = "-".join([vnc_kube_config.cluster_name(), name, 'sg']) ns_sg_fq_name.append(ns_sg) sg_list = [default_sg_fq_name, ns_sg_fq_name] try: # If the namespace is isolated, delete its virtual network. if self._is_namespace_isolated(name): vn_name = self._get_namespace_vn_name(name) self._delete_isolated_ns_virtual_network( name, vn_name=vn_name, proj_fq_name=proj_fq_name) # delete default-sg and ns-sg security groups security_groups = project.get_security_groups() for sg_uuid in security_groups: sg = SecurityGroupKM.get(sg_uuid) if sg and sg.fq_name in sg_list[:]: self._vnc_lib.security_group_delete(id=sg_uuid) sg_list.remove(sg.fq_name) if not len(sg_list): break # delete the label cache if project: self._clear_namespace_label_cache(namespace_id, project) # delete the namespace self._delete_namespace(name) # If namespace=project, delete the project if vnc_kube_config.cluster_project_name(name) == name: self._vnc_lib.project_delete(fq_name=proj_fq_name) except: pass
def _get_loadbalancer_id_or_none(self, service_name, service_namespace): """ Get ID of loadbalancer given service name and namespace. Return None if loadbalancer for the given service does not exist. """ service_info = self._kube.get_resource( 'services', service_name, service_namespace) if service_info is None or 'metadata' not in service_info: return None service_uid = service_info['metadata'].get('uid') if not service_uid: return None lb_name = VncCommon.make_name(service_name, service_uid) project_fq_name = vnc_kube_config.cluster_project_fq_name( service_namespace) lb_fq_name = project_fq_name + [lb_name] try: loadbalancer = self._vnc_lib.loadbalancer_read(fq_name=lb_fq_name) except NoIdError: return None if loadbalancer is None: return None return loadbalancer.uuid
def _delete_virtual_network(self, ns_name, vn_name): """ Delete the virtual network associated with this namespace. """ # First lookup the cache for the entry. vn = VirtualNetworkKM.find_by_name_or_uuid(vn_name) if not vn: return proj_fq_name = vnc_kube_config.cluster_project_fq_name(ns_name) try: vn_obj = self._vnc_lib.virtual_network_read(fq_name=vn.fq_name) # Delete/cleanup ipams allocated for this network. ipam_refs = vn_obj.get_network_ipam_refs() if ipam_refs: proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) for ipam in ipam_refs: ipam_obj = NetworkIpam( name=ipam['to'][-1], parent_obj=proj_obj) vn_obj.del_network_ipam(ipam_obj) self._vnc_lib.virtual_network_update(vn_obj) except NoIdError: pass # Delete the network. self._vnc_lib.virtual_network_delete(id=vn.uuid) # Delete the network from cache. VirtualNetworkKM.delete(vn.uuid)
def _create_iip(self, pod_name, pod_namespace, vn_obj, vmi): # Instance-ip for pods are ALWAYS allocated from pod ipam on this # VN. Get the subnet uuid of the pod ipam on this VN, so we can request # an IP from it. vn = VirtualNetworkKM.find_by_name_or_uuid(vn_obj.get_uuid()) if not vn: # It is possible our cache may not have the VN yet. Locate it. vn = VirtualNetworkKM.locate(vn_obj.get_uuid()) pod_ipam_subnet_uuid = vn.get_ipam_subnet_uuid( vnc_kube_config.pod_ipam_fq_name()) # Create instance-ip. display_name = VncCommon.make_display_name(pod_namespace, pod_name) iip_uuid = str(uuid.uuid1()) iip_name = VncCommon.make_name(pod_name, iip_uuid) iip_obj = InstanceIp(name=iip_name, subnet_uuid=pod_ipam_subnet_uuid, display_name=display_name) iip_obj.uuid = iip_uuid iip_obj.add_virtual_network(vn_obj) # Creation of iip requires the vmi vnc object. vmi_obj = self._vnc_lib.virtual_machine_interface_read( fq_name=vmi.fq_name) iip_obj.add_virtual_machine_interface(vmi_obj) InstanceIpKM.add_annotations(self, iip_obj, pod_namespace, pod_name) try: self._vnc_lib.instance_ip_create(iip_obj) except RefsExistError: self._vnc_lib.instance_ip_update(iip_obj) InstanceIpKM.locate(iip_obj.uuid) return iip_obj
def _delete_virtual_network(self, ns_name, vn_name): """ Delete the virtual network associated with this namespace. """ # First lookup the cache for the entry. vn = VirtualNetworkKM.find_by_name_or_uuid(vn_name) if not vn: return proj_fq_name = vnc_kube_config.cluster_project_fq_name(ns_name) try: vn_obj = self._vnc_lib.virtual_network_read(fq_name=vn.fq_name) # Delete/cleanup ipams allocated for this network. ipam_refs = vn_obj.get_network_ipam_refs() if ipam_refs: proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) for ipam in ipam_refs: ipam_obj = NetworkIpam( name=ipam['to'][-1], parent_obj=proj_obj) vn_obj.del_network_ipam(ipam_obj) self._vnc_lib.virtual_network_update(vn_obj) except RefsExistError as e: # Delete of custom network when it is still in use is not # supported yet. Log deletion attempt and return without deleting VN self._logger.error("%s: Cannot delete Network %s . %s" %(self._name, vn_name, str(e))) return except NoIdError: pass # Delete the network. self._vnc_lib.virtual_network_delete(id=vn.uuid) # Delete the network from cache. VirtualNetworkKM.delete(vn.uuid)
def _get_project(self, service_namespace): proj_fq_name =\ vnc_kube_config.cluster_project_fq_name(service_namespace) try: proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) return proj_obj except NoIdError: return None
def test_create_resources(self): vnc_kubernetes.VncKubernetes(self.args, Mock()) default_proj_name = vnc_kubernetes_config.cluster_project_name('default') kube_system_proj_name = vnc_kubernetes_config.cluster_project_name('kube-system') # Verify projects system_proj = self.verify_if_created('project', kube_system_proj_name, ['default-domain']) default_proj = self.verify_if_created('project', default_proj_name, ['default-domain']) self.verify_if_synchronized(vnc_kubernetes.ProjectKM, system_proj) self.verify_if_synchronized(vnc_kubernetes.ProjectKM, default_proj) # Verify cluster pod network net = self.verify_if_created('virtual-network', 'cluster-default-pod-network', ['default-domain', default_proj_name]) self.verify_if_synchronized(vnc_kubernetes.VirtualNetworkKM, net) ipam_refs = net.get_network_ipam_refs() self.assertEquals(1, len(ipam_refs)) self.assertEquals([], ipam_refs[0]['attr'].ipam_subnets) # Verify pod ipam pod_ipam = self.verify_if_created('network-ipam', self.args.cluster_name + '-pod-ipam', ['default-domain', default_proj_name]) self.verify_if_synchronized(vnc_kubernetes.NetworkIpamKM, pod_ipam) self.assertEquals('flat-subnet', pod_ipam.get_ipam_subnet_method()) self.assertEquals(16, pod_ipam.get_ipam_subnets().subnets[0].subnet.get_ip_prefix_len()) self.assertEquals('10.10.0.0', pod_ipam.get_ipam_subnets().subnets[0].subnet.get_ip_prefix()) # Verify cluster service network net = self.verify_if_created( 'virtual-network', 'cluster-default-service-network', ['default-domain', default_proj_name]) self.verify_if_synchronized(vnc_kubernetes.VirtualNetworkKM, net) ipam_refs = net.get_network_ipam_refs() self.assertEquals(1, len(ipam_refs)) self.assertEquals([], ipam_refs[0]['attr'].ipam_subnets) # Verify service ipam service_ipam = self.verify_if_created('network-ipam', self.args.cluster_name +'-service-ipam', ['default-domain', default_proj_name]) self.verify_if_synchronized(vnc_kubernetes.NetworkIpamKM, service_ipam) self.assertEquals('flat-subnet', pod_ipam.get_ipam_subnet_method()) self.assertEquals(24, service_ipam.get_ipam_subnets().subnets[0].subnet.get_ip_prefix_len()) self.assertEquals('192.168.0.0', service_ipam.get_ipam_subnets().subnets[0].subnet.get_ip_prefix())
def _delete_policy(self, ns_name, proj_fq_name): policy_name = "-".join([vnc_kube_config.cluster_name(), ns_name, 'pod-service-np']) policy_fq_name = proj_fq_name[:] policy_fq_name.append(policy_name) try: self._vnc_lib.network_policy_delete(fq_name=policy_fq_name) except NoIdError: pass
def _update_security_groups(self, ns_name, proj_obj): def _get_rule(ingress, sg, prefix, ethertype): sgr_uuid = str(uuid.uuid4()) if sg: if ':' not in sg: sg_fq_name = proj_obj.get_fq_name_str() + ':' + sg else: sg_fq_name = sg addr = AddressType(security_group=sg_fq_name) elif prefix: addr = AddressType(subnet=SubnetType(prefix, 0)) local_addr = AddressType(security_group='local') if ingress: src_addr = addr dst_addr = local_addr else: src_addr = local_addr dst_addr = addr rule = PolicyRuleType(rule_uuid=sgr_uuid, direction='>', protocol='any', src_addresses=[src_addr], src_ports=[PortType(0, 65535)], dst_addresses=[dst_addr], dst_ports=[PortType(0, 65535)], ethertype=ethertype) return rule # create default security group sg_name = vnc_kube_config.get_default_sg_name(ns_name) DEFAULT_SECGROUP_DESCRIPTION = "Default security group" id_perms = IdPermsType(enable=True, description=DEFAULT_SECGROUP_DESCRIPTION) rules = [] ingress = True egress = True if ingress: rules.append(_get_rule(True, None, '0.0.0.0', 'IPv4')) rules.append(_get_rule(True, None, '::', 'IPv6')) if egress: rules.append(_get_rule(False, None, '0.0.0.0', 'IPv4')) rules.append(_get_rule(False, None, '::', 'IPv6')) sg_rules = PolicyEntriesType(rules) sg_obj = SecurityGroup(name=sg_name, parent_obj=proj_obj, id_perms=id_perms, security_group_entries=sg_rules) SecurityGroupKM.add_annotations(self, sg_obj, namespace=ns_name, name=sg_obj.name, k8s_type=self._k8s_event_type) try: self._vnc_lib.security_group_create(sg_obj) self._vnc_lib.chown(sg_obj.get_uuid(), proj_obj.get_uuid()) except RefsExistError: self._vnc_lib.security_group_update(sg_obj) sg = SecurityGroupKM.locate(sg_obj.get_uuid()) return sg
def _create_iip(self, pod_name, pod_namespace, vn_obj, vmi): # Instance-ip for pods are ALWAYS allocated from pod ipam on this # VN. Get the subnet uuid of the pod ipam on this VN, so we can request # an IP from it. vn = VirtualNetworkKM.find_by_name_or_uuid(vn_obj.get_uuid()) if not vn: # It is possible our cache may not have the VN yet. Locate it. vn = VirtualNetworkKM.locate(vn_obj.get_uuid()) if self._is_pod_network_isolated(pod_namespace): vn_namespace = pod_namespace else: vn_namespace = 'default' if self._is_ip_fabric_forwarding_enabled(vn_namespace): ipam_fq_name = vnc_kube_config.ip_fabric_ipam_fq_name() else: ipam_fq_name = vnc_kube_config.pod_ipam_fq_name() pod_ipam_subnet_uuid = vn.get_ipam_subnet_uuid(ipam_fq_name) # Create instance-ip. iip_uuid = str(uuid.uuid1()) iip_name = VncCommon.make_name(pod_name, iip_uuid) iip_obj = InstanceIp(name=iip_name, subnet_uuid=pod_ipam_subnet_uuid, display_name=iip_name) iip_obj.uuid = iip_uuid iip_obj.add_virtual_network(vn_obj) # Creation of iip requires the vmi vnc object. vmi_obj = self._vnc_lib.virtual_machine_interface_read( fq_name=vmi.fq_name) iip_obj.add_virtual_machine_interface(vmi_obj) InstanceIpKM.add_annotations(self, iip_obj, pod_namespace, pod_name) self._logger.debug("%s: Create IIP from ipam_fq_name [%s]" " pod_ipam_subnet_uuid [%s]" " vn [%s] vmi_fq_name [%s]" %\ (self._name, ipam_fq_name, pod_ipam_subnet_uuid, vn.name, vmi.fq_name)) try: self._vnc_lib.instance_ip_create(iip_obj) except RefsExistError: self._vnc_lib.instance_ip_update(iip_obj) InstanceIpKM.locate(iip_obj.uuid) return iip_obj
def __init__(self, network_policy_mgr): self._k8s_event_type = 'Namespace' super(VncNamespace, self).__init__(self._k8s_event_type) self._name = type(self).__name__ self._network_policy_mgr = network_policy_mgr self._vnc_lib = vnc_kube_config.vnc_lib() self._label_cache = vnc_kube_config.label_cache() self._args = vnc_kube_config.args() self._logger = vnc_kube_config.logger() self._queue = vnc_kube_config.queue() self._labels = XLabelCache(self._k8s_event_type) ip_fabric_fq_name = vnc_kube_config. \ cluster_ip_fabric_network_fq_name() self._ip_fabric_vn_obj = self._vnc_lib. \ virtual_network_read(fq_name=ip_fabric_fq_name) self._ip_fabric_policy = None self._cluster_service_policy = None self._nested_underlay_policy = None
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 _sync_pod_vm(self): vm_uuid_set = set(VirtualMachineKM.keys()) pod_uuid_set = set(PodKM.keys()) deleted_pod_set = vm_uuid_set - pod_uuid_set for pod_uuid in deleted_pod_set: vm = VirtualMachineKM.get(pod_uuid) if not vm or\ vm.owner != 'k8s' or\ vm.cluster != vnc_kube_config.cluster_name(): continue self._create_pod_event('delete', pod_uuid, vm) for uuid in pod_uuid_set: vm = VirtualMachineKM.get(uuid) if not vm or\ vm.owner != 'k8s' or\ vm.cluster != vnc_kube_config.cluster_name(): continue if not vm.virtual_router and vm.pod_node and vm.node_ip: self._link_vm_to_node(vm, vm.pod_node, vm.node_ip) return
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_cluster_network(self): proj_fq_name = vnc_kube_config.cluster_default_project_fq_name() proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) vn_obj = VirtualNetwork( name='cluster-network', parent_obj=proj_obj, address_allocation_mode='user-defined-subnet-only') ipam_fq_name = ['default-domain', 'default-project', 'default-network-ipam'] ipam_obj = self._vnc_lib.network_ipam_read(fq_name=ipam_fq_name) subnet_data = self._create_subnet_data('10.32.0.0/24') vn_obj.add_network_ipam(ipam_obj, subnet_data) return self._vnc_lib.virtual_network_create(vn_obj)
def _create_attach_policy(self, ns_name, proj_obj, ip_fabric_vn_obj, pod_vn_obj, service_vn_obj): if not self._cluster_service_policy: cluster_service_np_fq_name = \ vnc_kube_config.cluster_default_service_network_policy_fq_name() try: cluster_service_policy = self._vnc_lib. \ network_policy_read(fq_name=cluster_service_np_fq_name) except NoIdError: return self._cluster_service_policy = cluster_service_policy if not self._ip_fabric_policy: cluster_ip_fabric_np_fq_name = \ vnc_kube_config.cluster_ip_fabric_policy_fq_name() try: cluster_ip_fabric_policy = self._vnc_lib. \ network_policy_read(fq_name=cluster_ip_fabric_np_fq_name) except NoIdError: return self._ip_fabric_policy = cluster_ip_fabric_policy self._nested_underlay_policy = None if DBBaseKM.is_nested() and not self._nested_underlay_policy: try: name = vnc_kube_config.cluster_nested_underlay_policy_fq_name() self._nested_underlay_policy = \ self._vnc_lib.network_policy_read(fq_name=name) except NoIdError: return policy_name = "-".join([vnc_kube_config.cluster_name(), ns_name, 'pod-service-np']) #policy_name = '%s-default' %ns_name ns_default_policy = self._create_vn_vn_policy(policy_name, proj_obj, pod_vn_obj, service_vn_obj) self._attach_policy(pod_vn_obj, ns_default_policy, self._ip_fabric_policy, self._cluster_service_policy, self._nested_underlay_policy) self._attach_policy(service_vn_obj, ns_default_policy, self._ip_fabric_policy, self._nested_underlay_policy)
def __init__(self): self._name = type(self).__name__ self._vnc_lib = vnc_kube_config.vnc_lib() self._logger = vnc_kube_config.logger() self.proj_obj = None proj_name = vnc_kube_config.get_configured_project_name() if not vnc_kube_config.is_global_tags() and proj_name: proj_fq_name = vnc_kube_config.cluster_project_fq_name() try: self.proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) except NoIdError as e: self._logger.error( "Unable to locate project object for [%s]" ". Error [%s]" %\ (proj_fq_name, str(e))) self._logger.debug( "All tags for this cluster will created with be in " "global space as project object was not found.") else: self._logger.debug( "All tags will be created within the scope of project [%s]"%\ (proj_fq_name))
def __init__(self, service_mgr, network_policy_mgr): super(VncPod, self).__init__('Pod') self._name = type(self).__name__ self._vnc_lib = vnc_kube_config.vnc_lib() self._label_cache = vnc_kube_config.label_cache() self._service_mgr = service_mgr self._network_policy_mgr = network_policy_mgr self._queue = vnc_kube_config.queue() self._service_fip_pool = vnc_kube_config.service_fip_pool() self._args = vnc_kube_config.args() self._logger = vnc_kube_config.logger()
def vnc_namespace_add(self, namespace_id, name, labels): isolated_ns_ann = 'True' if self._is_namespace_isolated(name) \ else 'False' proj_fq_name = vnc_kube_config.cluster_project_fq_name(name) proj_obj = Project(name=proj_fq_name[-1], fq_name=proj_fq_name) ProjectKM.add_annotations(self, proj_obj, namespace=name, name=name, k8s_uuid=(namespace_id), isolated=isolated_ns_ann) try: self._vnc_lib.project_create(proj_obj) except RefsExistError: proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) project = ProjectKM.locate(proj_obj.uuid) # Validate the presence of annotated virtual network. ann_vn_fq_name = self._get_annotated_virtual_network(name) if ann_vn_fq_name: # Validate that VN exists. try: self._vnc_lib.virtual_network_read(ann_vn_fq_name) except NoIdError as e: self._logger.error( "Unable to locate virtual network [%s]" "annotated on namespace [%s]. Error [%s]" %\ (ann_vn_fq_name, name, str(e))) return None # If this namespace is isolated, create it own network. if self._is_namespace_isolated(name) == True: vn_name = self._get_namespace_vn_name(name) self._create_isolated_ns_virtual_network(ns_name=name, vn_name=vn_name, proj_obj=proj_obj) try: network_policy = self._get_network_policy_annotations(name) sg_dict = self._update_security_groups(name, proj_obj, network_policy) self._ns_sg[name] = sg_dict except RefsExistError: pass if project: self._update_namespace_label_cache(labels, namespace_id, project) return project
def _get_network(self, pod_id, pod_name, pod_namespace): """ Get virtual network to be associated with the pod. The heuristics to determine which virtual network to use for the pod is as follows: if (virtual network is annotated in the pod config): Use virtual network configured on the pod. else if (virtual network if annotated in the pod's namespace): Use virtual network configured on the namespace. else if (pod is in a isolated namespace): Use the virtual network associated with isolated namespace. else: Use the pod virtual network associated with kubernetes cluster. """ # Check for virtual-network configured on the pod. pod = PodKM.find_by_name_or_uuid(pod_id) if not pod: self._logger.notice("%s - Pod %s:%s:%s Not Found" "(Might Got Delete Event From K8s)" %(self._name, pod_namespace, pod_name, pod_id)) return vn_fq_name = pod.get_vn_fq_name() ns = self._get_namespace(pod_namespace) # FIXME: Check if ns is not None # Check of virtual network configured on the namespace. if not vn_fq_name: vn_fq_name = ns.get_annotated_network_fq_name() # If the pod's namespace is isolated, use the isolated virtual # network. if not vn_fq_name: if self._is_pod_network_isolated(pod_namespace): vn_fq_name = ns.get_isolated_network_fq_name() # Finally, if no network was found, default to the cluster # pod network. if not vn_fq_name: vn_fq_name = vnc_kube_config.cluster_default_network_fq_name() vn_obj = self._vnc_lib.virtual_network_read(fq_name=vn_fq_name) return vn_obj
def __init__(self, service_mgr, network_policy_mgr): super(VncPod, self).__init__('Pod') self._name = type(self).__name__ self._vnc_lib = vnc_kube_config.vnc_lib() self._label_cache = vnc_kube_config.label_cache() self._labels = XLabelCache('Pod') self._service_mgr = service_mgr self._network_policy_mgr = network_policy_mgr self._queue = vnc_kube_config.queue() self._args = vnc_kube_config.args() self._logger = vnc_kube_config.logger() self._kube = vnc_kube_config.kube() if not VncPod.vnc_pod_instance: VncPod.vnc_pod_instance = self
def _create_vmi(self, pod_name, pod_namespace, pod_id, vm_obj, vn_obj, parent_vmi): 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) display_name = VncCommon.make_display_name(pod_namespace, pod_name) vmi_obj = VirtualMachineInterface( name=name, parent_obj=proj_obj, virtual_machine_interface_properties=vmi_prop, display_name=display_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) 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 _create_isolated_ns_virtual_network(self, ns_name, vn_name, proj_obj): """ Create a virtual network for this namespace. """ vn = VirtualNetwork( name=vn_name, parent_obj=proj_obj, virtual_network_properties=VirtualNetworkType(forwarding_mode='l3'), address_allocation_mode='flat-subnet-only') # Add annotatins on this isolated virtual-network. VirtualNetworkKM.add_annotations(self, vn, namespace=ns_name, name=ns_name, isolated='True') try: vn_uuid = self._vnc_lib.virtual_network_create(vn) except RefsExistError: vn_obj = self._vnc_lib.virtual_network_read( fq_name=vn.get_fq_name()) vn_uuid = vn_obj.uuid # Instance-Ip for pods on this VN, should be allocated from # cluster pod ipam. Attach the cluster pod-ipam object # to this virtual network. ipam_fq_name = vnc_kube_config.pod_ipam_fq_name() ipam_obj = self._vnc_lib.network_ipam_read( fq_name=ipam_fq_name) vn.add_network_ipam(ipam_obj, VnSubnetsType([])) # Update VN. self._vnc_lib.virtual_network_update(vn) # Cache the virtual network. VirtualNetworkKM.locate(vn_uuid) # Cache network info in namespace entry. self._set_namespace_virtual_network(ns_name, vn.get_fq_name()) return vn_uuid
def _vnc_create_sg(self, np_spec, namespace, name, uuid=None, **kwargs_annotations): proj_fq_name = vnc_kube_config.cluster_project_fq_name(namespace) proj_obj = Project(name=proj_fq_name[-1], fq_name=proj_fq_name, parent='domain') sg_obj = SecurityGroup(name=name, parent_obj=proj_obj) if uuid: sg_obj.uuid = uuid if np_spec: kwargs_annotations.update({'np_spec': json.dumps(np_spec)}) self._set_sg_annotations(namespace, name, sg_obj, **kwargs_annotations) try: self._vnc_lib.security_group_create(sg_obj) except Exception: self._logger.error("%s - %s SG Not Created" % (self._name, name)) return None sg = SecurityGroupKM.locate(sg_obj.uuid) return sg
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 __init__(self, tag_mgr=None): self._k8s_event_type = 'Ingress' super(VncIngress, self).__init__(self._k8s_event_type) self._name = type(self).__name__ self._args = vnc_kube_config.args() self._queue = vnc_kube_config.queue() self._vnc_lib = vnc_kube_config.vnc_lib() self._logger = vnc_kube_config.logger() self._kube = vnc_kube_config.kube() self._label_cache = vnc_kube_config.label_cache() self._labels = XLabelCache(self._k8s_event_type) self.tag_mgr = tag_mgr self._ingress_label_cache = {} self._default_vn_obj = None self._fip_pool_obj = None self.service_lb_mgr = ServiceLbManager() self.service_ll_mgr = ServiceLbListenerManager() self.service_lb_pool_mgr = ServiceLbPoolManager() self.service_lb_member_mgr = ServiceLbMemberManager()
def _update_security_groups(self, ns_name, proj_obj, network_policy): def _get_rule(ingress, sg, prefix, ethertype): sgr_uuid = str(uuid.uuid4()) if sg: if ':' not in sg: sg_fq_name = proj_obj.get_fq_name_str() + ':' + sg else: sg_fq_name = sg addr = AddressType(security_group=sg_fq_name) elif prefix: addr = AddressType(subnet=SubnetType(prefix, 0)) local_addr = AddressType(security_group='local') if ingress: src_addr = addr dst_addr = local_addr else: src_addr = local_addr dst_addr = addr rule = PolicyRuleType(rule_uuid=sgr_uuid, direction='>', protocol='any', src_addresses=[src_addr], src_ports=[PortType(0, 65535)], dst_addresses=[dst_addr], dst_ports=[PortType(0, 65535)], ethertype=ethertype) return rule sg_dict = {} # create default security group sg_name = "-".join( [vnc_kube_config.cluster_name(), ns_name, 'default']) DEFAULT_SECGROUP_DESCRIPTION = "Default security group" id_perms = IdPermsType(enable=True, description=DEFAULT_SECGROUP_DESCRIPTION) rules = [] ingress = True egress = True if network_policy and 'ingress' in network_policy: ingress_policy = network_policy['ingress'] if ingress_policy and 'isolation' in ingress_policy: isolation = ingress_policy['isolation'] if isolation == 'DefaultDeny': ingress = False if ingress: rules.append(_get_rule(True, None, '0.0.0.0', 'IPv4')) rules.append(_get_rule(True, None, '::', 'IPv6')) if egress: rules.append(_get_rule(False, None, '0.0.0.0', 'IPv4')) rules.append(_get_rule(False, None, '::', 'IPv6')) sg_rules = PolicyEntriesType(rules) sg_obj = SecurityGroup(name=sg_name, parent_obj=proj_obj, id_perms=id_perms, security_group_entries=sg_rules) SecurityGroupKM.add_annotations(self, sg_obj, namespace=ns_name, name=sg_obj.name, k8s_type=self._k8s_event_type) try: self._vnc_lib.security_group_create(sg_obj) self._vnc_lib.chown(sg_obj.get_uuid(), proj_obj.get_uuid()) except RefsExistError: self._vnc_lib.security_group_update(sg_obj) sg_obj = self._vnc_lib.security_group_read(sg_obj.fq_name) sg_uuid = sg_obj.get_uuid() SecurityGroupKM.locate(sg_uuid) sg_dict[sg_name] = sg_uuid # create namespace security group ns_sg_name = "-".join([vnc_kube_config.cluster_name(), ns_name, 'sg']) NAMESPACE_SECGROUP_DESCRIPTION = "Namespace security group" id_perms = IdPermsType(enable=True, description=NAMESPACE_SECGROUP_DESCRIPTION) sg_obj = SecurityGroup(name=ns_sg_name, parent_obj=proj_obj, id_perms=id_perms, security_group_entries=None) SecurityGroupKM.add_annotations(self, sg_obj, namespace=ns_name, name=sg_obj.name, k8s_type=self._k8s_event_type) try: self._vnc_lib.security_group_create(sg_obj) self._vnc_lib.chown(sg_obj.get_uuid(), proj_obj.get_uuid()) except RefsExistError: pass sg_obj = self._vnc_lib.security_group_read(sg_obj.fq_name) sg_uuid = sg_obj.get_uuid() SecurityGroupKM.locate(sg_uuid) sg_dict[ns_sg_name] = sg_uuid return sg_dict
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 __init__(self): super(ServiceLbMemberManager, self).__init__('ServiceLbMember') self._vnc_lib = vnc_kube_config.vnc_lib() self.logger = vnc_kube_config.logger()
def get_service_label(cls, service_name): """ Construct a service label. """ key = "-".join([vnc_kube_config.cluster_name(), 'svc']) value = service_name return {key: value}
def _get_ingress_firewall_rule_name(cls, ns_name, ingress_name, svc_name): return "-".join([ vnc_kube_config.cluster_name(), "Ingress", ns_name, ingress_name, svc_name ])
def get_ingress_label_name(cls, ns_name, name): return "-".join([vnc_kube_config.cluster_name(), ns_name, name])
def _get_namespace_service_vn_name(self, ns_name): return vnc_kube_config.cluster_name() + \ '-' + ns_name + "-service-network"
def _get_namespace_firewall_egress_rule_name(self, ns_name): return "-".join([ vnc_kube_config.cluster_name(), self._k8s_event_type, ns_name, "egress" ])
def vnc_namespace_add(self, namespace_id, name, labels): isolated_ns_ann = 'True' if self._is_namespace_isolated(name) \ else 'False' # Check if policy enforcement is enabled at project level. # If not, then security will be enforced at VN level. if DBBaseKM.is_nested(): # In nested mode, policy is always enforced at network level. # This is so that we do not enforce policy on other virtual # networks that may co-exist in the current project. secure_project = False else: secure_project = vnc_kube_config.is_secure_project_enabled() secure_vn = not secure_project proj_fq_name = vnc_kube_config.cluster_project_fq_name(name) proj_obj = Project(name=proj_fq_name[-1], fq_name=proj_fq_name) ProjectKM.add_annotations(self, proj_obj, namespace=name, name=name, k8s_uuid=(namespace_id), isolated=isolated_ns_ann) try: self._vnc_lib.project_create(proj_obj) except RefsExistError: proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) project = ProjectKM.locate(proj_obj.uuid) # Validate the presence of annotated virtual network. ann_vn_fq_name = self._get_annotated_virtual_network(name) if ann_vn_fq_name: # Validate that VN exists. try: self._vnc_lib.virtual_network_read(ann_vn_fq_name) except NoIdError as e: self._logger.error( "Unable to locate virtual network [%s]" "annotated on namespace [%s]. Error [%s]" %\ (ann_vn_fq_name, name, str(e))) # If this namespace is isolated, create it own network. if self._is_namespace_isolated(name) == True or name == 'default': vn_name = self._get_namespace_pod_vn_name(name) if self._is_ip_fabric_forwarding_enabled(name): ipam_fq_name = vnc_kube_config.ip_fabric_ipam_fq_name() ipam_obj = self._vnc_lib.network_ipam_read( fq_name=ipam_fq_name) provider = self._ip_fabric_vn_obj else: ipam_fq_name = vnc_kube_config.pod_ipam_fq_name() ipam_obj = self._vnc_lib.network_ipam_read( fq_name=ipam_fq_name) provider = None pod_vn = self._create_isolated_ns_virtual_network( ns_name=name, vn_name=vn_name, vn_type='pod-network', proj_obj=proj_obj, ipam_obj=ipam_obj, provider=provider, enforce_policy=secure_vn) # Cache pod network info in namespace entry. self._set_namespace_pod_virtual_network(name, pod_vn.get_fq_name()) vn_name = self._get_namespace_service_vn_name(name) ipam_fq_name = vnc_kube_config.service_ipam_fq_name() ipam_obj = self._vnc_lib.network_ipam_read(fq_name=ipam_fq_name) service_vn = self._create_isolated_ns_virtual_network( ns_name=name, vn_name=vn_name, vn_type='service-network', ipam_obj=ipam_obj, proj_obj=proj_obj, enforce_policy=secure_vn) # Cache service network info in namespace entry. self._set_namespace_service_virtual_network( name, service_vn.get_fq_name()) self._create_attach_policy(name, proj_obj, self._ip_fabric_vn_obj, pod_vn, service_vn) try: self._update_security_groups(name, proj_obj) except RefsExistError: pass if project: self._update_namespace_label_cache(labels, namespace_id, project) # If requested, enforce security policy at project level. if secure_project: proj_obj = self._vnc_lib.project_read(id=project.uuid) self._vnc_lib.set_tags( proj_obj, self._labels.get_labels_dict( VncSecurityPolicy.cluster_aps_uuid)) return project
def vnc_namespace_add(self, namespace_id, name, labels): isolated_ns_ann = 'True' if self._is_namespace_isolated(name) \ else 'False' proj_fq_name = vnc_kube_config.cluster_project_fq_name(name) proj_obj = Project(name=proj_fq_name[-1], fq_name=proj_fq_name) ProjectKM.add_annotations(self, proj_obj, namespace=name, name=name, k8s_uuid=(namespace_id), isolated=isolated_ns_ann) try: self._vnc_lib.project_create(proj_obj) except RefsExistError: proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) project = ProjectKM.locate(proj_obj.uuid) # Validate the presence of annotated virtual network. ann_vn_fq_name = self._get_annotated_virtual_network(name) if ann_vn_fq_name: # Validate that VN exists. try: self._vnc_lib.virtual_network_read(ann_vn_fq_name) except NoIdError as e: self._logger.error( "Unable to locate virtual network [%s]" "annotated on namespace [%s]. Error [%s]" %\ (ann_vn_fq_name, name, str(e))) return None # If this namespace is isolated, create it own network. if self._is_namespace_isolated(name) == True: vn_name = self._get_namespace_pod_vn_name(name) ipam_fq_name = vnc_kube_config.pod_ipam_fq_name() ipam_obj = self._vnc_lib.network_ipam_read(fq_name=ipam_fq_name) pod_vn = self._create_isolated_ns_virtual_network( \ ns_name=name, vn_name=vn_name, proj_obj=proj_obj, ipam_obj=ipam_obj, provider=self._ip_fabric_vn_obj) # Cache pod network info in namespace entry. self._set_namespace_pod_virtual_network(name, pod_vn.get_fq_name()) vn_name = self._get_namespace_service_vn_name(name) ipam_fq_name = vnc_kube_config.service_ipam_fq_name() ipam_obj = self._vnc_lib.network_ipam_read(fq_name=ipam_fq_name) service_vn = self._create_isolated_ns_virtual_network( \ ns_name=name, vn_name=vn_name, ipam_obj=ipam_obj,proj_obj=proj_obj) # Cache service network info in namespace entry. self._set_namespace_service_virtual_network( name, service_vn.get_fq_name()) self._create_attach_policy(name, proj_obj, \ self._ip_fabric_vn_obj, pod_vn, service_vn) try: network_policy = self._get_network_policy_annotations(name) sg_dict = self._update_security_groups(name, proj_obj, network_policy) self._ns_sg[name] = sg_dict except RefsExistError: pass if project: self._update_namespace_label_cache(labels, namespace_id, project) return project
def _associate_security_groups(vmi_obj, proj_obj, ns): sg_name = "-".join([vnc_kube_config.cluster_name(), ns, 'default-sg']) sg_obj = SecurityGroup(sg_name, proj_obj) vmi_obj.add_security_group(sg_obj) return
def validate_cluster_security_policy(cls): # If APS does not exist for this cluster, then there is nothing to do. if not cls.cluster_aps_uuid: return True aps = ApplicationPolicySetKM.find_by_name_or_uuid(cls.cluster_aps_uuid) # If we are not able to local APS in cache, then there is nothing to do. if not aps: return True # If APS does not match this cluster name, then there is nothing to do. if aps.name != vnc_kube_config.cluster_name(): return True # Update the APS, so we have the latest state. aps.update() fw_policy_uuids = aps.get_firewall_policies() # If there are no firewall policies on this APS yet, there is nothing # to verify. if not fw_policy_uuids: if cls.ingress_svc_fw_policy_uuid and\ cls.deny_all_fw_policy_uuid and\ cls.allow_all_fw_policy_uuid: return False else: return True # Validate that ingress firewall policy is the first policy of the # cluster owned firewall policies in the APS. if cls.ingress_svc_fw_policy_uuid: for fw_policy_uuid in fw_policy_uuids: fw_policy = FirewallPolicyKM.find_by_name_or_uuid( fw_policy_uuid) if not fw_policy: continue # Filter out policies not owned by this cluster. if fw_policy.cluster_name != vnc_kube_config.cluster_name(): continue # The first policy to reach here should be ingress policy. # Else return validation failure. if cls.ingress_svc_fw_policy_uuid == fw_policy_uuid: break vnc_kube_config.logger().error( "%s - Ingress FW Policy [%s] not the first policy on APS [%s]"\ %(cls.name, cls.ingress_svc_fw_policy_uuid, aps.name)) return False # Validate that deny and allow policies of this cluster are found on # on this APS. # The allow policy should follow the deny policy. deny_all_fw_policy_index = None allow_all_fw_policy_index = None if cls.deny_all_fw_policy_uuid and cls.allow_all_fw_policy_uuid: for index, fw_policy_uuid in enumerate(fw_policy_uuids): fw_policy = FirewallPolicyKM.find_by_name_or_uuid( fw_policy_uuid) if not fw_policy: continue # Filter out policies not owned by this cluster. if fw_policy.cluster_name != vnc_kube_config.cluster_name(): continue # Allow policy should follow the deny policy. # If not, return validation failure. if deny_all_fw_policy_index: if cls.allow_all_fw_policy_uuid == fw_policy_uuid: allow_all_fw_policy_index = index break elif cls.deny_all_fw_policy_uuid == fw_policy_uuid: deny_all_fw_policy_index = index # If we are unable to locate deny or allow policy, return validation # failure. if not deny_all_fw_policy_index or not allow_all_fw_policy_index: if cls.deny_all_fw_policy_uuid and not deny_all_fw_policy_index: vnc_kube_config.logger().error( "%s - deny-all FW Policy [%s] not found on APS [%s]"\ %(cls.name, cls.deny_all_fw_policy_uuid, aps.name)) if cls.allow_all_fw_policy_uuid and not allow_all_fw_policy_index: vnc_kube_config.logger().error( "%s - allow-all FW Policy [%s] not found (or not found"\ " after deny-all policy) on APS [%s]"\ %(cls.name, cls.allow_all_fw_policy_uuid, aps.name)) return False # Validation succeeded. All is well. return True
def setUp(self, *args, **kwargs): super(VncEndpointsNestedTest, self).setUp(*args, **kwargs) self.default_vn = self._vnc_lib.virtual_network_read( fq_name=VncKubernetesConfig.cluster_default_network_fq_name())
def recreate_cluster_security_policy(cls): # If APS does not exist for this cluster, then there is nothing to do. if not cls.cluster_aps_uuid: return aps = ApplicationPolicySetKM.find_by_name_or_uuid(cls.cluster_aps_uuid) # If APS does not match this cluster name, then there is nothing to do. if aps.name != vnc_kube_config.cluster_name(): return # Update the APS, so we have the latest state. aps_obj = cls.vnc_lib.application_policy_set_read( id=cls.cluster_aps_uuid) aps.update() vnc_kube_config.logger().debug( "%s - Remove existing firewall policies of cluster from APS [%s]"\ %(cls.name, aps.name)) # To begin with, remove all existing firewall policies of this cluster # from the APS. fw_policy_uuids = aps.get_firewall_policies() removed_firewall_policies = [] for fw_policy_uuid in fw_policy_uuids if fw_policy_uuids else []: fw_policy = FirewallPolicyKM.find_by_name_or_uuid(fw_policy_uuid) # Filter out policies not owned by this cluster. if fw_policy.cluster_name != vnc_kube_config.cluster_name(): continue # De-link the firewall policy from APS. try: fw_policy_obj = cls.vnc_lib.firewall_policy_read( id=fw_policy_uuid) except NoIdError: raise aps_obj.del_firewall_policy(fw_policy_obj) removed_firewall_policies.append(fw_policy_uuid) # If we need to remove some policies, update the object accordingly. if removed_firewall_policies: cls.vnc_lib.application_policy_set_update(aps_obj) aps.update() # Derive the sequence number we can use to start recreating firewall # policies. If there are existing policies that dont belong and are # not managed by the cluster, recreate the cluster firewall policies # to the tail. fw_policy_refs = aps.get_firewall_policy_refs_sorted() # Lets begin with the assumption that we are the first policy. sequence = cls.construct_sequence_number('1.0') if fw_policy_refs: # Get the sequence number of the last policy on this APS. last_entry_sequence = fw_policy_refs[-1]['attr'].get_sequence() # Construct the next sequence number to use. sequence = cls.construct_sequence_number( float(last_entry_sequence) + float('1.0')) # Filter our infra created firewall policies. try: removed_firewall_policies.remove(cls.ingress_svc_fw_policy_uuid) except ValueError: pass try: removed_firewall_policies.remove(cls.deny_all_fw_policy_uuid) except ValueError: pass try: removed_firewall_policies.remove(cls.allow_all_fw_policy_uuid) except ValueError: pass # Reconstruct the policies in the order we want them to be. add_firewall_policies = [cls.ingress_svc_fw_policy_uuid] +\ removed_firewall_policies+\ [cls.deny_all_fw_policy_uuid]+\ [cls.allow_all_fw_policy_uuid] # Attach the policies to the APS. for fw_policy_uuid in add_firewall_policies: vnc_kube_config.logger().debug( "%s - Recreate FW policy [%s] on APS [%s] at sequence [%s]"\ %(cls.name, fw_policy_uuid, aps.name, sequence.get_sequence())) try: fw_policy_obj = cls.vnc_lib.firewall_policy_read( id=fw_policy_uuid) except NoIdError: raise aps_obj.add_firewall_policy(fw_policy_obj, sequence) sequence = cls.construct_sequence_number( float(sequence.get_sequence()) + float('1.0')) # Update the APS. cls.vnc_lib.application_policy_set_update(aps_obj)
def sync_cluster_security_policy(cls): """ Synchronize K8s network policies with Contrail Security policy. Expects that FW policies on the APS are in proper order. Returns a list of orphaned or invalid firewall policies. """ # If APS does not exist for this cluster, then there is nothing to do. if not cls.cluster_aps_uuid: return [] aps = ApplicationPolicySetKM.find_by_name_or_uuid(cls.cluster_aps_uuid) if not aps: return [] # If APS does not match this cluster name, then there is nothing to do. if aps.name != vnc_kube_config.cluster_name(): return [] # Get the current list of firewall policies on the APS. fw_policy_uuids = aps.get_firewall_policies() # Construct list of firewall policies that belong to the cluster. cluster_firewall_policies = [] for fw_policy_uuid in fw_policy_uuids: fw_policy = FirewallPolicyKM.find_by_name_or_uuid(fw_policy_uuid) if fw_policy.cluster_name != vnc_kube_config.cluster_name(): continue cluster_firewall_policies.append(fw_policy_uuid) # We are interested only in policies created by k8s user via network # policy. These policies are sequenced between the infra created ingress # policy and infra created deny-all policy. try: start_index = cluster_firewall_policies.index( cls.ingress_svc_fw_policy_uuid) end_index = cluster_firewall_policies.index( cls.deny_all_fw_policy_uuid) curr_user_firewall_policies =\ cluster_firewall_policies[start_index+1:end_index] except ValueError: return [] # Get list of user created network policies. configured_network_policies = NetworkPolicyKM.get_configured_policies() for nw_policy_uuid in configured_network_policies: np = NetworkPolicyKM.find_by_name_or_uuid(nw_policy_uuid) if not np or not np.get_vnc_fq_name(): continue # Decipher the firewall policy corresponding to the network policy. fw_policy_uuid = FirewallPolicyKM.get_fq_name_to_uuid( np.get_vnc_fq_name().split(":")) if not fw_policy_uuid: # We are yet to process this network policy. continue # A firewall policy was found but it is not inbetween the infra # created policies as expected. Add it again so it will be inserted # in the right place. if fw_policy_uuid not in curr_user_firewall_policies: cls.add_firewall_policy(fw_policy_uuid) else: # Filter out processed policies. curr_user_firewall_policies.remove(fw_policy_uuid) # Return orphaned firewall policies that could not be validated against # user created network policy. headless_fw_policy_uuids = curr_user_firewall_policies return headless_fw_policy_uuids
def __init__(self): super(ServiceLbManager, self).__init__('ServiceLoadBalancer') self._vnc_lib = vnc_kube_config.vnc_lib() self.logger = vnc_kube_config.logger() self._labels = XLabelCache('ServiceLoadBalancer')
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) # Update tags. self._set_tags_on_pod_vmi(pod_id) return vm vn_obj = self._get_default_network(pod_id, pod_name, pod_namespace) if not vn_obj: return pod = PodKM.find_by_name_or_uuid(pod_id) total_interface_count = len(pod.networks) + 1 # network_status: Dict of network name to vmi_uuid network_status = {} proj_fq_name = vnc_kube_config.cluster_project_fq_name(pod_namespace) proj_obj = self._vnc_lib.project_read(fq_name=proj_fq_name) vm_obj = self._create_vm(pod_namespace, pod_id, pod_name, labels, proj_obj.uuid) index = str(0) + "/" + str(total_interface_count) default_network = {'network': 'default'} vmi_uuid = self.vnc_pod_vmi_create(pod_id, pod_name, pod_namespace, pod_node, node_ip, vm_obj, vn_obj, proj_obj, vm_vmi, index, default_network) network_status['cluster-wide-default'] = vmi_uuid for idx, network in enumerate(pod.networks, start=1): net_namespace = pod_namespace net_name = network['network'] if 'namespace' in network: net_namespace = network['namespace'] vn_obj = self._get_user_defined_network(net_name, net_namespace) index = str(idx) + "/" + str(total_interface_count) vmi_uuid = self.vnc_pod_vmi_create(pod_id, pod_name, pod_namespace, pod_node, node_ip, vm_obj, vn_obj, proj_obj, vm_vmi, index, network) network_status[net_name] = 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) self._set_tags_on_pod_vmi(pod_id) # Update network-status in pod description self._update_network_status(pod_name, pod_namespace, network_status) return vm
def _get_network_pod_ipam_name(self, nw_name): return vnc_kube_config.cluster_name() + \ '-' + nw_name + '-pod-ipam'
def _get_network_pod_vn_name(self, nw_name): return vnc_kube_config.cluster_name() + \ '-' + nw_name + "-pod-network"
def _get_cluster_network(self): return VirtualNetworkKM.find_by_name_or_uuid( vnc_kube_config.cluster_default_network_name())