Exemple #1
0
    def _get_session_static_rules(
        self,
        imsi: str,
        apn: str,
    ) -> List[StaticRuleInstall]:
        """
        Get the list of static rules to be installed for a subscriber
        NOTE: Remove "IMSI" prefix from imsi argument.
        """
        if imsi not in self._apn_rules_by_sid:
            return []

        sub_apn_policies = self._apn_rules_by_sid[imsi]
        assigned_static_rules = []  # type: List[StaticRuleInstall]
        # Add global rules
        global_rules = self._get_global_static_rules(sub_apn_policies)
        assigned_static_rules += \
            list(map(lambda id: StaticRuleInstall(rule_id=id),
                     global_rules))
        # Add APN specific rules
        for apn_policy_set in sub_apn_policies.rules_per_apn:
            if apn_policy_set.apn != apn:
                continue
            # Only add rules if the APN matches
            static_rule_ids = self._get_static_rules(apn_policy_set)
            assigned_static_rules +=\
                list(map(lambda id: StaticRuleInstall(rule_id=id),
                         static_rule_ids))

        return assigned_static_rules
    def EnableStaticRules(
        self,
        request: EnableStaticRuleRequest,
        context,
    ) -> Void:
        """
        Associate the static rules with the specified subscriber.
        Also send a RAR to sessiond to install the specified rules for the
        subscriber.
        """
        try:
            self._subscriberdb_stub.EnableStaticRules(request)
        except grpc.RpcError:
            logging.error('Unable to enable rules for subscriber %s. ',
                          request.imsi)
            context.set_code(grpc.StatusCode.NOT_FOUND)
            context.set_details('Failed to update rule assignments in orc8r')
            return Void()

        rules_to_install = self._get_rules(request.rule_ids, request.base_names)
        rar = PolicyReAuthRequest(
            # Leave session id empty, re-auth for all sessions
            imsi=request.imsi,
            rules_to_install=[
                StaticRuleInstall(rule_id=rule_id)
                for rule_id in rules_to_install
            ],
        )
        success = self._reauth_handler.handle_policy_re_auth(rar)
        if not success:
            context.set_code(grpc.StatusCode.UNKNOWN)
            context.set_details('Failed to enable all static rules for '
                                'subscriber. Partial update may have succeeded')
        return Void()
Exemple #3
0
 def _get_rules_for_imsi(self, imsi: str) -> List[StaticRuleInstall]:
     try:
         info = self._subscriberdb_stub.GetSubscriberData(NetworkID(id=imsi))
         return [StaticRuleInstall(rule_id=rule_id)
                 for rule_id in info.lte.assigned_policies]
     except grpc.RpcError:
         logging.error('Unable to find data for subscriber %s', imsi)
         return []
    def test_SuccessfulUpdate(self):
        """
        Test the happy path where updates come in for added rules, and sessiond
        accepts the RAR without issue.
        """
        install_dict = {}
        handler = ReAuthHandler(
            install_dict,
            MockSessionProxyResponderStub(),
        )

        rar = PolicyReAuthRequest(
            imsi='s1',
            rules_to_install=[
                StaticRuleInstall(rule_id=rule_id) for rule_id in ['p1', 'p2']
            ],
        )
        handler.handle_policy_re_auth(rar)
        s1_policies = install_dict['s1'].installed_policies
        expected = 2
        self.assertEqual(
            len(s1_policies),
            expected,
            'There should be 2 installed policies for s1',
        )
        self.assertTrue(
            'p1' in s1_policies,
            'Policy p1 should be marked installed for p1',
        )

        rar = PolicyReAuthRequest(
            imsi='s1',
            rules_to_install=[StaticRuleInstall(rule_id='p3')],
        )
        handler.handle_policy_re_auth(rar)
        s1_policies = install_dict['s1'].installed_policies
        expected = 3
        self.assertEqual(
            len(s1_policies),
            expected,
            'There should be 3 installed policies for s1',
        )
        self.assertTrue(
            'p3' in s1_policies,
            'Policy p1 should be marked installed for p1',
        )
Exemple #5
0
    def _build_sub_rule_set(
        self,
        subscriber_id: str,
        sub_apn_policies: SubscriberPolicySet,
    ) -> RulesPerSubscriber:
        apn_rule_sets = []  # type: List[RuleSet]
        global_rules = self._get_global_static_rules(sub_apn_policies)

        for apn_policy_set in sub_apn_policies.rules_per_apn:
            # Static rule installs
            static_rule_ids = self._get_desired_static_rules(apn_policy_set)
            static_rules = []  # type: List[StaticRuleInstall]
            for rule_id in static_rule_ids:
                static_rules.append(StaticRuleInstall(rule_id=rule_id))
            # Add global rules
            for rule_id in global_rules:
                static_rules.append(StaticRuleInstall(rule_id=rule_id))

            # Dynamic rule installs
            dynamic_rules = []  # type: List[DynamicRuleInstall]
            # Build the rule id to be globally unique
            rule = DynamicRuleInstall(
                policy_rule=get_allow_all_policy_rule(
                    subscriber_id,
                    apn_policy_set.apn,
                ),
            )
            dynamic_rules.append(rule)

            # Build the APN rule set
            apn_rule_sets.append(
                RuleSet(
                    apply_subscriber_wide=False,
                    apn=apn_policy_set.apn,
                    static_rules=static_rules,
                    dynamic_rules=dynamic_rules,
                ),
            )

        return RulesPerSubscriber(
            imsi=subscriber_id,
            rule_set=apn_rule_sets,
        )
Exemple #6
0
 def _get_rules_for_imsi(self, imsi: str) -> List[StaticRuleInstall]:
     """
     Get the list of static rules to be installed for a subscriber
     NOTE: Remove "IMSI" prefix from imsi argument.
     """
     try:
         info = self._subscriberdb_stub.GetSubscriberData(NetworkID(id=imsi))
         return [StaticRuleInstall(rule_id=rule_id)
                 for rule_id in info.lte.assigned_policies]
     except grpc.RpcError:
         logging.error('Unable to find data for subscriber %s', imsi)
         return []
Exemple #7
0
 def _generate_rar(
     self,
     subscriber_id: str,
     added_rules: List[str],
     removed_rules: List[str],
 ) -> PolicyReAuthRequest:
     rules_to_install = [
         StaticRuleInstall(rule_id=rule_id) for rule_id in added_rules
     ]
     return PolicyReAuthRequest(
         # Skip the session ID, so apply to all sessions of the subscriber
         imsi=subscriber_id,
         rules_to_install=rules_to_install,
         rules_to_remove=removed_rules,
         # No changes to dynamic rules
         # No event triggers
         # No additional usage monitoring credits
         # No QoS info
     )
    def test_Update(self):
        """
        Test the happy path where updates come in for rules, and sessiond
        accepts the SessionRules without issue.
        """

        # Expected call arguments to SetSessionRules
        allow_all_flow_list = [
            FlowDescription(
                match=FlowMatch(
                    direction=FlowMatch.Direction.Value("UPLINK"), ),
                action=FlowDescription.Action.Value("PERMIT"),
            ),
            FlowDescription(
                match=FlowMatch(
                    direction=FlowMatch.Direction.Value("DOWNLINK"), ),
                action=FlowDescription.Action.Value("PERMIT"),
            ),
        ]  # type: List[FlowDescription]
        no_tracking_type = PolicyRule.TrackingType.Value("NO_TRACKING")
        expected = SessionRules(rules_per_subscriber=[
            RulesPerSubscriber(
                imsi='imsi_1',
                rule_set=[
                    RuleSet(
                        apply_subscriber_wide=False,
                        apn="apn1",
                        static_rules=[
                            StaticRuleInstall(rule_id="p1"),
                        ],
                        dynamic_rules=[
                            DynamicRuleInstall(policy_rule=PolicyRule(
                                id="allowlist_sid-imsi_1-apn1",
                                priority=2,
                                flow_list=allow_all_flow_list,
                                tracking_type=no_tracking_type,
                            ))
                        ],
                    ),
                ]),
            RulesPerSubscriber(
                imsi='imsi_2',
                rule_set=[
                    RuleSet(
                        apply_subscriber_wide=False,
                        apn="apn1",
                        static_rules=[
                            StaticRuleInstall(rule_id="p5"),
                        ],
                        dynamic_rules=[
                            DynamicRuleInstall(policy_rule=PolicyRule(
                                id="allowlist_sid-imsi_2-apn1",
                                priority=2,
                                flow_list=allow_all_flow_list,
                                tracking_type=no_tracking_type,
                            ))
                        ],
                    ),
                ])
        ])

        # Setup the test
        apn_rules_dict = {}
        basenames_dict = {
            'bn1': ChargingRuleNameSet(RuleNames=['p5']),
            'bn2': ChargingRuleNameSet(RuleNames=['p6']),
        }
        stub = MockLocalSessionManagerStub()

        stub_call_args = []  # type: List[SessionRules]
        side_effect = get_SetSessionRules_side_effect(stub_call_args)
        stub.SetSessionRules = Mock(side_effect=side_effect)

        callback = ApnRuleMappingsStreamerCallback(
            stub,
            basenames_dict,
            apn_rules_dict,
        )

        # Construct a set of updates, keyed by subscriber ID
        updates = [
            DataUpdate(
                key="imsi_1",
                value=SubscriberPolicySet(rules_per_apn=[
                    ApnPolicySet(
                        apn="apn1",
                        assigned_base_names=[],
                        assigned_policies=["p1"],
                    ),
                ], ).SerializeToString(),
            ),
            DataUpdate(
                key="imsi_2",
                value=SubscriberPolicySet(rules_per_apn=[
                    ApnPolicySet(
                        apn="apn1",
                        assigned_base_names=["bn1"],
                        assigned_policies=[],
                    ),
                ], ).SerializeToString(),
            ),
        ]

        callback.process_update("stream", updates, False)

        # Since we used a stub which always succeeds when a RAR is made,
        # We should expect the assignments_dict to be updated
        imsi_1_policies = apn_rules_dict["imsi_1"]
        self.assertEqual(len(imsi_1_policies.rules_per_apn), 1,
                         'There should be 1 active APNs for imsi_1')
        self.assertEqual(len(stub_call_args), 1,
                         'Stub should have been called once')
        called_with = stub_call_args[0].SerializeToString()
        self.assertEqual(called_with, expected.SerializeToString(),
                         'SetSessionRules call has incorrect arguments')

        # Stream down a second update, and now IMSI_1 gets access to a new APN
        updates_2 = [
            DataUpdate(
                key="imsi_1",
                value=SubscriberPolicySet(rules_per_apn=[
                    ApnPolicySet(
                        apn="apn2",
                        assigned_base_names=["bn1"],
                        assigned_policies=[],
                    ),
                ], ).SerializeToString(),
            ),
            DataUpdate(
                key="imsi_2",
                value=SubscriberPolicySet(
                    global_base_names=["bn2"],
                    global_policies=[],
                    rules_per_apn=[
                        ApnPolicySet(
                            apn="apn1",
                            assigned_base_names=[],
                            assigned_policies=[],
                        ),
                    ],
                ).SerializeToString(),
            ),
        ]
        expected_2 = SessionRules(rules_per_subscriber=[
            RulesPerSubscriber(
                imsi='imsi_1',
                rule_set=[
                    RuleSet(
                        apply_subscriber_wide=False,
                        apn="apn2",
                        static_rules=[
                            StaticRuleInstall(rule_id="p5"),
                        ],
                        dynamic_rules=[
                            DynamicRuleInstall(policy_rule=PolicyRule(
                                id="allowlist_sid-imsi_1-apn2",
                                priority=2,
                                flow_list=allow_all_flow_list,
                                tracking_type=no_tracking_type,
                            ))
                        ],
                    ),
                ]),
            RulesPerSubscriber(
                imsi='imsi_2',
                rule_set=[
                    RuleSet(
                        apply_subscriber_wide=False,
                        apn="apn1",
                        static_rules=[
                            StaticRuleInstall(rule_id="p6"),
                        ],
                        dynamic_rules=[
                            DynamicRuleInstall(policy_rule=PolicyRule(
                                id="allowlist_sid-imsi_2-apn1",
                                priority=2,
                                flow_list=allow_all_flow_list,
                                tracking_type=no_tracking_type,
                            ))
                        ],
                    ),
                ]),
        ])

        callback.process_update("stream", updates_2, False)

        imsi_1_policies = apn_rules_dict["imsi_1"]
        self.assertEqual(len(imsi_1_policies.rules_per_apn), 1,
                         'There should be 1 active APNs for imsi_1')
        self.assertEqual(len(stub_call_args), 2,
                         'Stub should have been called twice')
        called_with = stub_call_args[1].SerializeToString()
        self.assertEqual(called_with, expected_2.SerializeToString(),
                         'SetSessionRules call has incorrect arguments')
Exemple #9
0
 def _get_static_rules(self) -> List[StaticRuleInstall]:
     """ Return a static rule for redirection to captive portal """
     if self.redirect_rule_name in self._rules:
         return [StaticRuleInstall(rule_id=self.redirect_rule_name)]
     return []
Exemple #10
0
 def _get_static_rule(self) -> StaticRuleInstall:
     """ Return a static rule for redirection to captive portal """
     return StaticRuleInstall(
         rule_id = self.redirect_rule_name,
     )