def tearDownClass(cls): for pod in list(PodKM): PodKM.delete(pod) for namespace in list(NamespaceKM): NamespaceKM.delete(namespace) super(VncPodTest, cls).tearDownClass()
def _delete_pod(self, testpod, uuid=None, spec=None, meta=None, wait=True): pod_del_event = self.create_event('Pod', spec if spec else testpod.spec, meta if meta else testpod.meta, 'DELETED') PodKM.delete(uuid if uuid else testpod.uuid) self.enqueue_event(pod_del_event) if wait: self.wait_for_all_tasks_done()
def tearDownClass(cls): for pod in list(PodKM): PodKM.delete(pod) for service in list(ServiceKM): ServiceKM.delete(service) for namespace in list(NamespaceKM): NamespaceKM.delete(namespace) super(VncEndpointsTestBase, cls).tearDownClass()
def tearDownClass(cls): for pod in list(PodKM): PodKM.delete(pod) for namespace in list(NamespaceKM): NamespaceKM.delete(namespace) # Cleanup the Vrouter object. cls.delete_virtual_router(cls.vrouter_obj.uuid) super(VncPodTest, cls).tearDownClass()
def _add_pod(self, pod_name, pod_namespace, pod_status): pod_uid = str(uuid.uuid4()) pod_spec = {'nodeName': 'test-node'} pod_meta = { 'name': pod_name, 'uid': pod_uid, 'namespace': pod_namespace, 'labels': {} } pod_add_event = self.create_event('Pod', pod_spec, pod_meta, 'ADDED') pod_add_event['object']['status'] = pod_status PodKM.locate(pod_uid, pod_add_event['object']) self.enqueue_event(pod_add_event) return pod_uid
def _create_update_pod(self, pod_name, pod_namespace, pod_status, eval_vn_dict, action, labels={}, req_uuid=None, wait=True): pod_uuid = req_uuid if req_uuid else str(uuid.uuid4()) pod_spec = {'nodeName': 'test-node'} pod_labels = labels pod_meta = { 'name': pod_name, 'uid': pod_uuid, 'namespace': pod_namespace, 'labels': pod_labels } if eval_vn_dict: pod_meta['annotations'] = { 'opencontrail.org/network': eval_vn_dict } pod_add_event = self.create_event('Pod', pod_spec, pod_meta, action) pod_add_event['object']['status'] = pod_status pod = PodKM.locate(pod_uuid, pod_add_event['object']) self.enqueue_event(pod_add_event) if wait: self.wait_for_all_tasks_done() return TestPod(pod.uuid, pod_meta, pod_spec)
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 else: self._check_pod_uuid_change(pod_id, pod_name) 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 = {} vm_obj = self._create_vm(pod_namespace, pod_id, pod_name, labels) index = str(0) + "/" + 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, vm_vmi,\ index, nw_name='default') network_status['cluster-wide-default'] = vmi_uuid for idx, network_name in enumerate(pod.networks, start=1): net_namespace = pod_namespace net_name = network_name # Check if network is in a different namespace than the pod's # namespace (ex: <namespace/<network>) if '/' in network_name: net_namespace, net_name = network_name.split('/') 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, net_namespace,\ pod_node, node_ip, vm_obj, vn_obj, vm_vmi,\ index, nw_name=net_name) 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 _delete_pod(self, pod_uuid): pod = PodKM.find_by_name_or_uuid(pod_uuid) self.assertIsNotNone(pod) pod_spec = self._construct_pod_spec(pod.nodename) pod_meta = self._construct_pod_meta(pod.name, pod_uuid, pod.namespace) super(VncPodLabelsTest, self)._delete_pod(None, pod_uuid, pod_spec, pod_meta)
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 uuid in deleted_pod_set: vm = VirtualMachineKM.get(uuid) if not vm or vm.owner != 'k8s': continue self._create_pod_event('delete', uuid, vm) return
def process(self, event): event_type = event['type'] kind = event['object'].get('kind') name = event['object']['metadata'].get('name') ns_id = event['object']['metadata'].get('uid') labels = dict(event['object']['metadata'].get('labels', {})) print("%s - Got %s %s %s:%s" % (self._name, event_type, kind, name, ns_id)) self._logger.debug("%s - Got %s %s %s:%s" % (self._name, event_type, kind, name, ns_id)) if event['type'] == 'ADDED' or event['type'] == 'MODIFIED': # Process label add. # We implicitly add a namespace label as well. labels['namespace'] = name self._labels.process(ns_id, labels) self.vnc_namespace_add(ns_id, name, labels) self.add_namespace_security_policy(ns_id) if event['type'] == 'MODIFIED' and self._get_namespace(name): # If labels on this namespace has changed, update the pods # on this namespace with current namespace labels. added_labels, removed_labels =\ self._get_namespace(name).get_changed_labels() namespace_pods = PodKM.get_namespace_pods(name) # Remove the old label first. # # 'Remove' must be done before 'Add', to account for the case # where, what got changed was the value for an existing label. # This is especially important as, remove label code only # considers the key while deleting the label. # # If Add is done before Remove, then the updated label that # was set by 'Add', will be deleted by the 'Remove' call. if removed_labels: VncPod.remove_labels(namespace_pods, removed_labels) if added_labels: VncPod.add_labels(namespace_pods, added_labels) elif event['type'] == 'DELETED': self.delete_namespace_security_policy(name) # Delete label deletes for this namespace. self._labels.process(ns_id) self.vnc_namespace_delete(ns_id, name) else: self._logger.warning('Unknown event type: "{}" Ignoring'.format( event['type']))
def process(self, event): event_type = event['type'] kind = event['object'].get('kind') name = event['object']['metadata'].get('name') ns_id = event['object']['metadata'].get('uid') labels = dict(event['object']['metadata'].get('labels', {})) print("%s - Got %s %s %s:%s" %(self._name, event_type, kind, name, ns_id)) self._logger.debug("%s - Got %s %s %s:%s" %(self._name, event_type, kind, name, ns_id)) if event['type'] == 'ADDED' or event['type'] == 'MODIFIED': # Process label add. # We implicitly add a namespace label as well. labels['namespace'] = name self._labels.process(ns_id, labels) self.vnc_namespace_add(ns_id, name, labels) self.add_namespace_security_policy(ns_id) if event['type'] == 'MODIFIED' and self._get_namespace(name): # If labels on this namespace has changed, update the pods # on this namespace with current namespace labels. added_labels, removed_labels =\ self._get_namespace(name).get_changed_labels() namespace_pods = PodKM.get_namespace_pods(name) # Remove the old label first. # # 'Remove' must be done before 'Add', to account for the case # where, what got changed was the value for an existing label. # This is especially important as, remove label code only # considers the key while deleting the label. # # If Add is done before Remove, then the updated label that # was set by 'Add', will be deleted by the 'Remove' call. if removed_labels: VncPod.remove_labels(namespace_pods, removed_labels) if added_labels: VncPod.add_labels(namespace_pods, added_labels) elif event['type'] == 'DELETED': self.delete_namespace_security_policy(name) # Delete label deletes for this namespace. self._labels.process(ns_id) self.vnc_namespace_delete(ns_id, name) else: self._logger.warning( 'Unknown event type: "{}" Ignoring'.format(event['type']))
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: pod = PodKM.get(uuid_) if not pod: continue self._link_vm_to_node(vm, pod.nodename, pod.host_ip) return
def _create_update_pod(self, pod_name, pod_namespace, pod_status, eval_vn_dict, action): pod_uuid = str(uuid.uuid4()) pod_spec = {'nodeName': 'test-node'} pod_labels = {} pod_meta = {'name': pod_name, 'uid': pod_uuid, 'namespace': pod_namespace, 'labels': pod_labels} if eval_vn_dict: pod_meta['annotations'] = { 'opencontrail.org/network': eval_vn_dict} pod_add_event = self.create_event('Pod', pod_spec, pod_meta, action) pod_add_event['object']['status'] = pod_status pod = PodKM.locate(pod_uuid, pod_add_event['object']) self.enqueue_event(pod_add_event) return TestPod(pod.uuid, pod_meta, pod_spec)
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': 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': 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 _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 uuid in deleted_pod_set: vm = VirtualMachineKM.get(uuid) if not vm: continue if not vm.annotations: continue for kvp in vm.annotations['key_value_pair'] or []: if kvp['key'] == 'owner' \ and kvp['value'] == 'k8s': self._create_pod_event('delete', uuid, vm) break return
def _sync_pod_vm(self): vm_uuid_list = list(VirtualMachineKM.keys()) pod_uuid_list = list(PodKM.keys()) for uuid in vm_uuid_list: if uuid in pod_uuid_list: continue vm = VirtualMachineKM.get(uuid) if not vm: continue if not vm.annotations: continue for kvp in vm.annotations['key_value_pair'] or []: if kvp['key'] == 'device_owner' \ and kvp['value'] == 'K8S:POD': self._create_pod_event('delete', uuid, vm) break return
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 _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_pod_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_pod_network_fq_name() vn_obj = self._vnc_lib.virtual_network_read(fq_name=vn_fq_name) return vn_obj
def _create_update_pod(self, pod_name, pod_namespace, pod_status, eval_vn_dict, action, labels={}, req_uuid=None, wait=True): pod_uuid = req_uuid if req_uuid else str(uuid.uuid4()) pod_spec = {'nodeName': 'test-node'} pod_labels = labels pod_meta = {'name': pod_name, 'uid': pod_uuid, 'namespace': pod_namespace, 'labels': pod_labels} if eval_vn_dict: pod_meta['annotations'] = { 'opencontrail.org/network': eval_vn_dict} self.set_mock_for_kube() pod_add_event = self.create_event('Pod', pod_spec, pod_meta, action) pod_add_event['object']['status'] = pod_status pod = PodKM.locate(pod_uuid, pod_add_event['object']) self.enqueue_event(pod_add_event) if wait: self.wait_for_all_tasks_done() return TestPod(pod.uuid, pod_meta, pod_spec)
def process(self, event): event_type = event['type'] kind = event['object'].get('kind') name = event['object']['metadata'].get('name') ns_id = event['object']['metadata'].get('uid') labels = dict(event['object']['metadata'].get('labels', {})) print("%s - Got %s %s %s:%s" % (self._name, event_type, kind, name, ns_id)) self._logger.debug("%s - Got %s %s %s:%s" % (self._name, event_type, kind, name, ns_id)) if event['type'] == 'ADDED' or event['type'] == 'MODIFIED': # Process label add. # We implicitly add a namespace label as well. labels['namespace'] = name self._labels.process(ns_id, labels) self.vnc_namespace_add(ns_id, name, labels) self.add_namespace_security_policy(ns_id) if event['type'] == 'MODIFIED' and self._get_namespace(name): # If labels on this namespace has changed, update the pods # on this namespace with current namespace labels. added_labels, removed_labels =\ self._get_namespace(name).get_changed_labels() namespace_pods = PodKM.get_namespace_pods(name) if added_labels: VncPod.add_labels(namespace_pods, added_labels) if removed_labels: VncPod.remove_labels(namespace_pods, removed_labels) elif event['type'] == 'DELETED': self.delete_namespace_security_policy(name) self.vnc_namespace_delete(ns_id, name) # Delete label deletes for this namespace. self._labels.process(ns_id) else: self._logger.warning('Unknown event type: "{}" Ignoring'.format( event['type']))
def _get_network(self, pod_id, 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) vn_fq_name = pod.get_vn_fq_name() ns = self._get_namespace(pod_namespace) # 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) == True: 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_project_fq_name() +\ [vnc_kube_config.cluster_default_network_name()] vn_obj = self._vnc_lib.virtual_network_read(fq_name=vn_fq_name) return vn_obj
def _delete_pod(self, testpod): pod_del_event = self.create_event('Pod', testpod.spec, testpod.meta, 'DELETED') PodKM.delete(testpod.uuid) self.enqueue_event(pod_del_event)
def _delete_pod(self, pod_uuid, pod_spec, pod_meta): pod_del_event = self.create_event('Pod', pod_spec, pod_meta, 'DELETED') PodKM.delete(pod_uuid) self.enqueue_event(pod_del_event)
def _get_host_ip(pod_name): pod = PodKM.find_by_name_or_uuid(pod_name) if pod: return pod.get_host_ip() return None
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