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 _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 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 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