Exemple #1
0
 def process_update(self, stream_name: str, updates: List[DataUpdate],
                    resync: bool):
     logging.info('Processing %d basename -> policy updates', len(updates))
     for update in updates:
         basename = ChargingRuleNameSet()
         basename.ParseFromString(update.value)
         self._basenames[update.key] = basename
Exemple #2
0
 def setUp(self):
     rating_groups_by_id = {
         1: RatingGroup(
             id=1,
             limit_type=RatingGroup.INFINITE_UNMETERED,
         ),
         2: RatingGroup(
             id=2,
             limit_type=RatingGroup.INFINITE_METERED,
         ),
     }
     basenames_dict = {
         'bn1': ChargingRuleNameSet(RuleNames=['p5']),
         'bn2': ChargingRuleNameSet(RuleNames=['p6']),
     }
     apn_rules_by_sid = {
         "IMSI1234":
         SubscriberPolicySet(rules_per_apn=[
             ApnPolicySet(
                 apn="apn1",
                 assigned_base_names=[],
                 assigned_policies=["redirect"],
             ),
         ], ),
         "IMSI2345":
         SubscriberPolicySet(rules_per_apn=[
             ApnPolicySet(
                 apn="apn1",
                 assigned_base_names=["bn1"],
                 assigned_policies=[],
             ),
             ApnPolicySet(
                 apn="apn2",
                 assigned_base_names=["bn2"],
                 assigned_policies=[],
             ),
         ], ),
         "IMSI3456":
         SubscriberPolicySet(
             global_base_names=["bn1"],
             global_policies=[],
             rules_per_apn=[
                 ApnPolicySet(
                     apn="apn1",
                     assigned_base_names=[],
                     assigned_policies=[],
                 ),
             ],
         ),
     }
     self.servicer = SessionRpcServicer(
         self._get_mconfig(),
         rating_groups_by_id,
         basenames_dict,
         apn_rules_by_sid,
     )
Exemple #3
0
    def test_SuccessfulUpdate(self):
        """
        Test the happy path where updates come in for added rules, and sessiond
        accepts the RAR without issue.
        """
        assignments_dict = {}
        basenames_dict = {
            'bn1': ChargingRuleNameSet(RuleNames=['p5']),
            'bn2': ChargingRuleNameSet(RuleNames=['p6']),
        }
        callback = RuleMappingsStreamerCallback(
            ReAuthHandler(assignments_dict, MockSessionProxyResponderStub1()),
            basenames_dict,
            assignments_dict,
        )

        # Construct a set of updates, keyed by subscriber ID
        updates = [
            DataUpdate(
                key="s1",
                value=AssignedPolicies(
                    assigned_policies=["p1", "p2"],
                    assigned_base_names=["bn1"],
                ).SerializeToString(),
            ),
            DataUpdate(
                key="s2",
                value=AssignedPolicies(
                    assigned_policies=["p2", "p3"], ).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

        s1_policies = assignments_dict["s1"].installed_policies
        expected = 3
        self.assertEqual(len(s1_policies), expected,
                         'There should be 3 active '
                         'policies for s1')
        self.assertTrue("p1" in s1_policies, 'Policy p1 should be active for '
                        'subscriber s1')
        self.assertTrue("p5" in s1_policies, 'Policy p5 should be active for '
                        'subscriber s1')

        s2_policies = assignments_dict["s2"].installed_policies
        expected = 2
        self.assertEqual(len(s2_policies), expected,
                         'There should be 2 active '
                         'policies for s2')
        self.assertTrue("p3" in s2_policies, 'Policy p3 should be active for '
                        'subscriber s2')
    def test_EnableStaticRules(self):
        """
        Check the happy path where everything succeeds.
        """
        rules_by_sid = {}
        rules_by_basename = {
            "bn1": ChargingRuleNameSet(RuleNames=["p4", "p5"], ),
        }
        reauth_handler = ReAuthHandler(
            rules_by_sid,
            MockSessionProxyResponderStub(),
        )

        servicer = PolicyRpcServicer(
            reauth_handler,
            rules_by_basename,
            MockPolicyAssignmentControllerStub(),
        )

        # Bind the rpc server to a free port
        thread_pool = futures.ThreadPoolExecutor(max_workers=10)
        rpc_server = grpc.server(thread_pool)
        port = rpc_server.add_insecure_port('0.0.0.0:0')

        # Create a mock "mconfig" for the servicer to use
        mconfig = unittest.mock.Mock()
        mconfig.ip_block = None

        # Add the servicer
        servicer.add_to_server(rpc_server)
        rpc_server.start()

        # Create a rpc stub
        channel = grpc.insecure_channel('0.0.0.0:{}'.format(port))
        stub = PolicyDBStub(channel)
        rules_by_basename["bn1"] = ChargingRuleNameSet(RuleNames=["p4",
                                                                  "p5"], )
        req = EnableStaticRuleRequest(
            imsi="s1",
            rule_ids=["p1", "p2", "p3"],
            base_names=["bn1"],
        )
        stub.EnableStaticRules(req)
        self.assertEqual(
            len(rules_by_sid["s1"].installed_policies),
            5,
            'After a successful update, Redis should be tracking '
            '5 active rules.',
        )
    def test_FailOrc8r(self):
        """ Check that nothing is updated if orc8r is unreachable """
        rules_by_sid = {}
        rules_by_basename = {
            "bn1": ChargingRuleNameSet(RuleNames=["p4", "p5"], ),
        }
        reauth_handler = ReAuthHandler(
            rules_by_sid,
            MockSessionProxyResponderStub(),
        )

        servicer = PolicyRpcServicer(
            reauth_handler,
            rules_by_basename,
            MockPolicyAssignmentControllerStub2(),
        )

        # Bind the rpc server to a free port
        thread_pool = futures.ThreadPoolExecutor(max_workers=10)
        rpc_server = grpc.server(thread_pool)
        port = rpc_server.add_insecure_port('0.0.0.0:0')

        # Create a mock "mconfig" for the servicer to use
        mconfig = unittest.mock.Mock()
        mconfig.ip_block = None

        # Add the servicer
        servicer.add_to_server(rpc_server)
        rpc_server.start()

        # Create a rpc stub
        channel = grpc.insecure_channel('0.0.0.0:{}'.format(port))
        stub = PolicyDBStub(channel)
        req = EnableStaticRuleRequest(
            imsi="s1",
            rule_ids=["p1", "p2", "p3"],
            base_names=["bn1"],
        )
        with self.assertRaises(grpc.RpcError):
            stub.EnableStaticRules(req)

        self.assertFalse(
            "s1" in rules_by_sid,
            "There should be no installed policies for s1",
        )
    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')