def _validate_network_policy_resources(self, name, uuid, spec={}, validate_delete=False, namespace=None): ns_name = namespace if namespace else self.ns_name np_event_obj = NetworkPolicyKM.find_by_name_or_uuid(uuid) if validate_delete: self.assertIsNone(np_event_obj) elif not spec: fw_policy_uuid = VncSecurityPolicy.get_firewall_policy_uuid( name, ns_name) fw_policy = FirewallPolicyKM.locate(fw_policy_uuid) self.assertIsNotNone(np_event_obj) self.assertIsNone(fw_policy) else: fw_policy_uuid = VncSecurityPolicy.get_firewall_policy_uuid( name, ns_name) fw_policy = FirewallPolicyKM.locate(fw_policy_uuid) self.assertIsNotNone(np_event_obj) self.assertIsNotNone(fw_policy) # Validate network policy spec. self._validate_spec(spec, fw_policy)
def add_firewall_rule(cls, fw_policy_uuid, fw_rule_uuid): try: fw_policy_obj = cls.vnc_lib.firewall_policy_read(id=fw_policy_uuid) except NoIdError: raise try: fw_rule_obj = cls.vnc_lib.firewall_rule_read(id=fw_rule_uuid) except NoIdError: raise last_entry_sequence = None rule_refs = fw_policy_obj.get_firewall_rule_refs() for rule in rule_refs if rule_refs else []: if fw_rule_uuid == rule['uuid']: return if last_entry_sequence < rule['attr'].get_sequence(): last_entry_sequence = rule['attr'].get_sequence() # Start with presumption that this is the first. sequence = cls.construct_sequence_number('1.0') if last_entry_sequence: sequence = cls.construct_sequence_number( float(last_entry_sequence) + float('1.0')) fw_policy_obj.add_firewall_rule(fw_rule_obj, sequence) cls.vnc_lib.firewall_policy_update(fw_policy_obj) FirewallPolicyKM.locate(fw_policy_obj.get_uuid())
def delete_firewall_rule(cls, fw_policy_uuid, fw_rule_uuid): # If policy or rule info is not provided, then there is nothing to do. if not fw_policy_uuid or not fw_rule_uuid: return try: fw_policy_obj = cls.vnc_lib.firewall_policy_read(id=fw_policy_uuid) except NoIdError: raise try: fw_rule_obj = cls.vnc_lib.firewall_rule_read(id=fw_rule_uuid) except NoIdError: return addr_grp_refs = fw_rule_obj.get_address_group_refs() fw_policy_obj.del_firewall_rule(fw_rule_obj) cls.vnc_lib.firewall_policy_update(fw_policy_obj) FirewallPolicyKM.locate(fw_policy_obj.get_uuid()) # Delete the rule. cls.vnc_lib.firewall_rule_delete(id=fw_rule_uuid) # Try to delete address groups allocated for this FW rule. for addr_grp in addr_grp_refs if addr_grp_refs else []: FWRule.delete_address_group(addr_grp['uuid'])
def delete_firewall_policy(cls, name, namespace, is_global=False): if not cls.cluster_aps_uuid: raise Exception("Cluster Application Policy Set not available.") # Get parent object for this firewall policy. aps_obj = cls.vnc_lib.application_policy_set_read( id=cls.cluster_aps_uuid) try: pm_obj = cls.vnc_lib.policy_management_read( fq_name=aps_obj.get_parent_fq_name()) except NoIdError: raise fw_policy_fq_name = pm_obj.get_fq_name() +\ [cls.get_firewall_policy_name(name, namespace, is_global)] fw_policy_uuid = FirewallPolicyKM.get_fq_name_to_uuid( fw_policy_fq_name) if not fw_policy_uuid: # We are not aware of this firewall policy. return fw_policy = FirewallPolicyKM.locate(fw_policy_uuid) fw_policy_rules = fw_policy.firewall_rules # Remove deny all firewall rule, if any. if fw_policy.deny_all_rule_uuid: VncSecurityPolicy.delete_firewall_rule( VncSecurityPolicy.deny_all_fw_policy_uuid, fw_policy.deny_all_rule_uuid) # Remove egress deny all firewall rule, if any. if fw_policy.egress_deny_all_rule_uuid: VncSecurityPolicy.delete_firewall_rule( VncSecurityPolicy.deny_all_fw_policy_uuid, fw_policy.egress_deny_all_rule_uuid) for rule_uuid in fw_policy_rules: try: VncSecurityPolicy.delete_firewall_rule(fw_policy_uuid, rule_uuid) except: raise cls.remove_firewall_policy(name, namespace) try: cls.vnc_lib.firewall_policy_delete(id=fw_policy_uuid) FirewallPolicyKM.delete(fw_policy_uuid) except: raise
def remove_firewall_policy(cls, name, namespace, is_global=False): if not cls.cluster_aps_uuid: raise Exception("Cluster Application Policy Set not available.") aps_obj = cls.vnc_lib.application_policy_set_read( id=cls.cluster_aps_uuid) try: pm_obj = cls.vnc_lib.policy_management_read( fq_name=aps_obj.get_parent_fq_name()) except NoIdError: raise fw_policy_fq_name = pm_obj.get_fq_name() +\ [cls.get_firewall_policy_name(name, namespace, is_global)] fw_policy_uuid = FirewallPolicyKM.get_fq_name_to_uuid( fw_policy_fq_name) if not fw_policy_uuid: # We are not aware of this firewall policy. return 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) cls.vnc_lib.application_policy_set_update(aps_obj)
def get_firewall_policy_rule_uuid(cls, name, namespace, is_global=False): if not cls.cluster_aps_uuid: raise Exception("Cluster Application Policy Set not available.") aps = ApplicationPolicySetKM.locate(cls.cluster_aps_uuid) pm = PolicyManagementKM.locate(aps.parent_uuid) fw_policy_fq_name = pm.fq_name +\ [cls.get_firewall_policy_name(name, namespace, is_global)] fw_policy_uuid = FirewallPolicyKM.get_fq_name_to_uuid(fw_policy_fq_name) return fw_policy_uuid
def _validate_network_policy_resources(self, name, uuid, spec={}, validate_delete=False, namespace=None): ns_name = namespace if namespace else self.ns_name np_event_obj = NetworkPolicyKM.find_by_name_or_uuid(uuid) if validate_delete: self.assertIsNone(np_event_obj) elif not spec: fw_policy_uuid = VncSecurityPolicy.get_firewall_policy_uuid(name, ns_name) fw_policy = FirewallPolicyKM.locate(fw_policy_uuid) self.assertIsNotNone(np_event_obj) self.assertIsNone(fw_policy) else: fw_policy_uuid = VncSecurityPolicy.get_firewall_policy_uuid(name, ns_name) fw_policy = FirewallPolicyKM.locate(fw_policy_uuid) self.assertIsNotNone(np_event_obj) self.assertIsNotNone(fw_policy) # Validate network policy spec. self._validate_spec(spec, fw_policy)
def _create_network_policy_delete_event(self, fw_policy_uuid): """ Self-create a network policy delete event. """ event = {} object_ = {} event['type'] = 'DELETED' object_['kind'] = 'NetworkPolicy' object_['metadata'] = {} fw_policy = FirewallPolicyKM.find_by_name_or_uuid(fw_policy_uuid) object_['metadata']['uid'] = fw_policy.k8s_uuid object_['metadata']['name'] = fw_policy.k8s_name object_['metadata']['namespace'] = fw_policy.k8s_namespace event['object'] = object_ self._queue.put(event) return
def test_periodic_validate_with_user_policies(self): """ Validate network policy periodic self-healing when multiple user created policies are present. """ np_uuid_dict = {} test_range = list(range(1, 10)) for i in test_range: np_spec = {'podSelector': {}, 'ingress': [{}]} np_name = "-".join([unittest.TestCase.id(self), str(i)]) np_uuid_dict[i] = self._add_update_network_policy(np_name, np_spec) self._validate_network_policy_resources(np_name, np_uuid_dict[i], np_spec) # Check if we have a valid config to start with. valid = VncSecurityPolicy.validate_cluster_security_policy() self.assertTrue(valid) # Get some basic object handles. self.assertIsNotNone(VncSecurityPolicy.allow_all_fw_policy_uuid) fw_policy_obj = self._vnc_lib.firewall_policy_read( id=VncSecurityPolicy.allow_all_fw_policy_uuid) aps_obj = self._get_default_application_policy_set() self.assertIsNotNone(fw_policy_obj) self.assertIsNotNone(aps_obj) # Detach allow-all policy from APS to introduce error. aps_obj.del_firewall_policy(fw_policy_obj) self._vnc_lib.application_policy_set_update(aps_obj) # Verify that validation of APS will fail. valid = VncSecurityPolicy.validate_cluster_security_policy() self.assertFalse(valid) # Fix the inconsisteny in APS. VncSecurityPolicy.recreate_cluster_security_policy() # Verify that validation of APS will succeed now. valid = VncSecurityPolicy.validate_cluster_security_policy() self.assertTrue(valid) # # After self-healing, verify that the first on the APS, the FW policies # are ordered as follows: # - Ingress-svc fw policy # - User created policies # - Deny-all fw policy # - Allow-all fw policy # previous_sequence = None aps = ApplicationPolicySetKM.locate(aps_obj.get_uuid()) aps.update() fw_policy_refs = aps.get_firewall_policy_refs_sorted() ingress_fw_policy_idx = None for index, fw_policy_ref in enumerate(fw_policy_refs): fw_policy = FirewallPolicyKM.locate(fw_policy_ref['uuid']) if fw_policy.owner and\ fw_policy.cluster_name == self.cluster_name(): self.assertTrue(fw_policy.uuid == VncSecurityPolicy.ingress_svc_fw_policy_uuid) ingress_fw_policy_idx = index break last_user_policy_index = None loop_start_index = ingress_fw_policy_idx + 1 for i in test_range: np_name = "-".join([unittest.TestCase.id(self), str(i)]) fw_policy_name = VncSecurityPolicy.get_firewall_policy_name( np_name, self.ns_name, False) for index, fw_policy in enumerate( fw_policy_refs[loop_start_index:]): if fw_policy_name == fw_policy['to'][-1]: if previous_sequence: self.assertTrue(previous_sequence < \ fw_policy['attr']['sequence']) previous_sequence = fw_policy['attr']['sequence'] last_user_policy_index = loop_start_index + index break deny_all_policy_index = None loop_start_index = last_user_policy_index + 1 for index, fw_policy_ref in enumerate( fw_policy_refs[loop_start_index:]): fw_policy = FirewallPolicyKM.locate(fw_policy_ref['uuid']) if fw_policy.cluster_name and\ fw_policy.cluster_name == self.cluster_name(): self.assertTrue(fw_policy.uuid == VncSecurityPolicy.deny_all_fw_policy_uuid) deny_all_policy_index = loop_start_index + index break loop_start_index = deny_all_policy_index + 1 for fw_policy_ref in fw_policy_refs[loop_start_index:]: fw_policy = FirewallPolicyKM.locate(fw_policy_ref['uuid']) if fw_policy.cluster_name and\ fw_policy.cluster_name == self.cluster_name(): self.assertTrue(fw_policy.uuid == VncSecurityPolicy.allow_all_fw_policy_uuid) break for i in test_range: self._delete_network_policy(unittest.TestCase.id(self), np_uuid_dict[i]) self._validate_network_policy_resources(np_name, np_uuid_dict[i], np_spec, validate_delete=True)
def create_firewall_policy(cls, name, namespace, spec, tag_last=False, is_global=False, k8s_uuid=None): if not cls.cluster_aps_uuid: raise Exception("Cluster Application Policy Set not available.") # Get parent object for this firewall policy. aps_obj = cls.vnc_lib.application_policy_set_read( id=cls.cluster_aps_uuid) try: pm_obj = cls.vnc_lib.policy_management_read( fq_name=aps_obj.get_parent_fq_name()) except NoIdError: raise fw_policy_obj = FirewallPolicy( cls.get_firewall_policy_name(name, namespace, is_global), pm_obj) custom_ann_kwargs = {} custom_ann_kwargs['k8s_uuid'] = k8s_uuid curr_fw_policy = None fw_rules_del_candidates = set() # If this firewall policy already exists, get its uuid. fw_policy_uuid = VncSecurityPolicy.get_firewall_policy_uuid( name, namespace, is_global) if fw_policy_uuid: # # FW policy exists. # Check for modidifcation to its spec. # If not modifications are found, return the uuid of policy. # curr_fw_policy = FirewallPolicyKM.locate(fw_policy_uuid) if curr_fw_policy and curr_fw_policy.spec: if curr_fw_policy.spec == json.dumps(spec): # Input spec is same as existing spec. Nothing to do. # Just return the uuid. return fw_policy_uuid # Get the current firewall rules on this policy. # All rules are delete candidates as any of them could have # changed. fw_rules_del_candidates = curr_fw_policy.firewall_rules # Annotate the FW policy object with input spec. # This will be used later to identify and validate subsequent modify # or add (i.e post restart) events. custom_ann_kwargs['spec'] = json.dumps(spec) # Check if we are being asked to place this firewall policy in the end # of fw policy list in its Application Policy Set. # If yes, tag accordingly. if tag_last: custom_ann_kwargs['tail'] = "True" # Parse input spec and construct the list of rules for this FW policy. fw_rules = [] deny_all_rule_uuid = None egress_deny_all_rule_uuid = None if spec is not None: fw_rules, deny_all_rule_uuid, egress_deny_all_rule_uuid =\ FWRule.parser(name, namespace, pm_obj, spec) for rule in fw_rules: try: rule_uuid = cls.vnc_lib.firewall_rule_create(rule) except RefsExistError: cls.vnc_lib.firewall_rule_update(rule) rule_uuid = rule.get_uuid() # The rule is in use and needs to stay. # Remove it from delete candidate collection. if fw_rules_del_candidates and\ rule_uuid in fw_rules_del_candidates: fw_rules_del_candidates.remove(rule_uuid) rule_obj = cls.vnc_lib.firewall_rule_read(id=rule_uuid) FirewallRuleKM.locate(rule_uuid) fw_policy_obj.add_firewall_rule( rule_obj, cls.construct_sequence_number(fw_rules.index(rule))) if deny_all_rule_uuid: VncSecurityPolicy.add_firewall_rule( VncSecurityPolicy.deny_all_fw_policy_uuid, deny_all_rule_uuid) custom_ann_kwargs['deny_all_rule_uuid'] = deny_all_rule_uuid if egress_deny_all_rule_uuid: VncSecurityPolicy.add_firewall_rule( VncSecurityPolicy.deny_all_fw_policy_uuid, egress_deny_all_rule_uuid) custom_ann_kwargs['egress_deny_all_rule_uuid'] =\ egress_deny_all_rule_uuid FirewallPolicyKM.add_annotations( VncSecurityPolicy.vnc_security_policy_instance, fw_policy_obj, namespace, name, None, **custom_ann_kwargs) try: fw_policy_uuid = cls.vnc_lib.firewall_policy_create(fw_policy_obj) except RefsExistError: # Remove existing firewall rule refs on this fw policy. # Once existing firewall rules are remove, firewall policy will # be updated with rules correspoinding to current input spec. for rule in fw_rules_del_candidates: cls.delete_firewall_rule(fw_policy_uuid, rule) cls.vnc_lib.firewall_policy_update(fw_policy_obj) fw_policy_uuid = fw_policy_obj.get_uuid() fw_policy_obj = cls.vnc_lib.firewall_policy_read(id=fw_policy_uuid) FirewallPolicyKM.locate(fw_policy_uuid) return fw_policy_uuid
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 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 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 test_periodic_validate_with_user_policies(self): """ Validate network policy periodic self-healing when multiple user created policies are present. """ np_uuid_dict={} test_range = range(1, 10) for i in test_range: np_spec = { 'podSelector': {}, 'ingress': [{}] } np_name = "-".join([unittest.TestCase.id(self), str(i)]) np_uuid_dict[i] = self._add_update_network_policy(np_name, np_spec) self._validate_network_policy_resources(np_name, np_uuid_dict[i], np_spec) # Check if we have a valid config to start with. valid = VncSecurityPolicy.validate_cluster_security_policy() self.assertTrue(valid) # Get some basic object handles. self.assertIsNotNone(VncSecurityPolicy.allow_all_fw_policy_uuid) fw_policy_obj = self._vnc_lib.firewall_policy_read( id=VncSecurityPolicy.allow_all_fw_policy_uuid) aps_obj = self._get_default_application_policy_set() self.assertIsNotNone(fw_policy_obj) self.assertIsNotNone(aps_obj) # Detach allow-all policy from APS to introduce error. aps_obj.del_firewall_policy(fw_policy_obj) self._vnc_lib.application_policy_set_update(aps_obj) # Verify that validation of APS will fail. valid = VncSecurityPolicy.validate_cluster_security_policy() self.assertFalse(valid) # Fix the inconsisteny in APS. VncSecurityPolicy.recreate_cluster_security_policy() # Verify that validation of APS will succeed now. valid = VncSecurityPolicy.validate_cluster_security_policy() self.assertTrue(valid) # # After self-healing, verify that the first on the APS, the FW policies # are ordered as follows: # - Ingress-svc fw policy # - User created policies # - Deny-all fw policy # - Allow-all fw policy # previous_sequence = None aps = ApplicationPolicySetKM.locate(aps_obj.get_uuid()) aps.update() fw_policy_refs = aps.get_firewall_policy_refs_sorted() ingress_fw_policy_idx = None for index, fw_policy_ref in enumerate(fw_policy_refs): fw_policy = FirewallPolicyKM.locate(fw_policy_ref['uuid']) if fw_policy.owner and\ fw_policy.cluster_name == self.cluster_name(): self.assertTrue(fw_policy.uuid == VncSecurityPolicy.ingress_svc_fw_policy_uuid) ingress_fw_policy_idx = index break last_user_policy_index = None loop_start_index = ingress_fw_policy_idx+1 for i in test_range: np_name = "-".join([unittest.TestCase.id(self), str(i)]) fw_policy_name = VncSecurityPolicy.get_firewall_policy_name(np_name, self.ns_name, False) for index, fw_policy in enumerate(fw_policy_refs[loop_start_index:]): if fw_policy_name == fw_policy['to'][-1]: if previous_sequence: self.assertTrue(previous_sequence < \ fw_policy['attr']['sequence']) previous_sequence = fw_policy['attr']['sequence'] last_user_policy_index = loop_start_index + index break deny_all_policy_index = None loop_start_index = last_user_policy_index + 1 for index, fw_policy_ref in enumerate(fw_policy_refs[loop_start_index:]): fw_policy = FirewallPolicyKM.locate(fw_policy_ref['uuid']) if fw_policy.cluster_name and\ fw_policy.cluster_name == self.cluster_name(): self.assertTrue(fw_policy.uuid == VncSecurityPolicy.deny_all_fw_policy_uuid) deny_all_policy_index = loop_start_index + index break loop_start_index = deny_all_policy_index + 1 for fw_policy_ref in fw_policy_refs[loop_start_index:]: fw_policy = FirewallPolicyKM.locate(fw_policy_ref['uuid']) if fw_policy.cluster_name and\ fw_policy.cluster_name == self.cluster_name(): self.assertTrue(fw_policy.uuid == VncSecurityPolicy.allow_all_fw_policy_uuid) break for i in test_range: self._delete_network_policy(unittest.TestCase.id(self), np_uuid_dict[i]) self._validate_network_policy_resources(np_name, np_uuid_dict[i], np_spec, validate_delete=True)
def create_firewall_policy(cls, name, namespace, spec, tag_last=False, is_global=False): if not cls.cluster_aps_uuid: raise Exception("Cluster Application Policy Set not available.") # Get parent object for this firewall policy. aps_obj = cls.vnc_lib.application_policy_set_read( id=cls.cluster_aps_uuid) try: pm_obj = cls.vnc_lib.policy_management_read( fq_name=aps_obj.get_parent_fq_name()) except NoIdError: raise fw_policy_obj = FirewallPolicy( cls.get_firewall_policy_name(name, namespace, is_global), pm_obj) custom_ann_kwargs = {} if tag_last: custom_ann_kwargs['tail'] = "True" # Parse input spec and construct the list of rules for this FW policy. fw_rules = [] deny_all_rule_uuid = None if spec is not None: fw_rules, deny_all_rule_uuid = FWRule.parser(name, namespace, pm_obj, spec) for rule in fw_rules: try: rule_uuid = cls.vnc_lib.firewall_rule_create(rule) except RefsExistError: cls.vnc_lib.firewall_rule_update(rule) rule_uuid = rule.get_uuid() rule_obj = cls.vnc_lib.firewall_rule_read(id=rule_uuid) FirewallRuleKM.locate(rule_uuid) #FirewallSequence( # sequence=cls.construct_sequence_number(fw_rules.index(rule))) fw_policy_obj.add_firewall_rule(rule_obj, cls.construct_sequence_number(fw_rules.index(rule))) if deny_all_rule_uuid: VncSecurityPolicy.add_firewall_rule( VncSecurityPolicy.deny_all_fw_policy_uuid, deny_all_rule_uuid) custom_ann_kwargs['deny_all_rule_uuid'] = deny_all_rule_uuid FirewallPolicyKM.add_annotations( VncSecurityPolicy.vnc_security_policy_instance, fw_policy_obj, namespace, name, None, **custom_ann_kwargs) try: fw_policy_uuid = cls.vnc_lib.firewall_policy_create(fw_policy_obj) except RefsExistError: cls.vnc_lib.firewall_policy_update(fw_policy_obj) fw_policy_uuid = fw_policy_obj.get_uuid() fw_policy_obj = cls.vnc_lib.firewall_policy_read(id=fw_policy_uuid) FirewallPolicyKM.locate(fw_policy_uuid) return fw_policy_uuid