示例#1
0
    def DestroyPolicy(self, request, context):
        """Delete a policy."""
        asn_str, client = get_client_from_metadata(
            context.invocation_metadata())
        asn = ASN(asn_str)

        if request.asn != asn_str:
            context.abort(grpc.StatusCode.PERMISSION_DENIED,
                          "Cannot delete policies of other ASes")

        serializer = PolicyProtoSerializer(message=request)
        if not serializer.is_valid():
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          _fmt_validation_errors(serializer.errors))
        try:
            policy = serializer.get()
        except ObjectDoesNotExist:
            context.abort(grpc.StatusCode.NOT_FOUND, "Policy does not exist")

        _assert_policy_write_permission(context, asn, client, request.vlan)
        policy.delete()

        # Update links and notify clients
        policy_resolver.update_accepted_peers(policy.vlan, policy.asys)
        policy_resolver.update_links(policy.vlan, policy.asys)

        return Empty()
示例#2
0
    def _set_policies(
            self, request, context
    ) -> Tuple[typing.List[peering_pb2.Policy], typing.List[str]]:
        # Delete old policies. Parse the new ones, and try saving them to the DB.
        # Returns the unsuccessful policies and matching error descriptions.
        # context.abort() is called on fatal errors to abort the RPC and trigger a transaction
        # rollback.
        asn_str, client = get_client_from_metadata(
            context.invocation_metadata())
        asn = ASN(asn_str)

        # Delete previous policies
        if request.vlan:
            try:
                vlan_id = VLAN.objects.get(name=request.vlan).id
            except VLAN.DoesNotExist:
                context.abort(grpc.StatusCode.NOT_FOUND, "VLAN does not exist")
                _assert_policy_write_permission(context, asn, client,
                                                request.vlan)
            _delete_policies(asn, vlan_id)
        else:
            _assert_policy_write_permission(context, asn, client)
            _delete_policies(asn)

        # Create new policies
        rejected_policies = []
        errors = []
        for policy in request.policies:
            serializer = PolicyProtoSerializer(message=policy)

            if policy.asn != asn_str:
                rejected_policies.append(policy)
                errors.append("Policy ASN belongs to foreign AS")
                continue

            if request.vlan and policy.vlan != request.vlan:
                rejected_policies.append(policy)
                errors.append("VLAN excluded by filter")
                continue

            if not serializer.is_valid():
                rejected_policies.append(policy)
                errors.append(_fmt_validation_errors(serializer.errors))
                continue

            try:
                serializer.save()
            except ValidationError as e:
                msg, _ = _translate_validation_errors(e)
                rejected_policies.append(policy)
                errors.append(msg)
                continue

        # Update links and notify clients
        asys = AS.objects.get(asn=asn)
        for vlan in asys.get_connected_vlans():
            policy_resolver.update_accepted_peers(vlan, asys)
            policy_resolver.update_links(vlan, asys)

        return rejected_policies, errors
    def test_priority(self):
        """Test priority of AS-level over Owner-level over ISD-level policies."""
        vlan = self.vlan[0]

        # Accept 2-ff00:0:4 -> 1-ff00:0:1
        # Accept 2-ff00:0:5 -> 1-ff00:0:1
        AsPeerPolicy.objects.create(vlan=vlan, asys=self.asys[4], peer_as=self.asys[1], accept=True)
        AsPeerPolicy.objects.create(vlan=vlan, asys=self.asys[5], peer_as=self.asys[1], accept=True)
        update_accepted_peers(vlan, self.asys[4])
        update_accepted_peers(vlan, self.asys[5])
        # Accept 1-ff00:0:1 -> ISD 2
        _add_isd_policy(vlan, self.asys[1], self.isd[1], True)
        self.assertEqual(self.asys[1].accept.count(), 2)
        self.assertEqual(_count_links(self.asys[1]), 2)
        self.assertTrue(_links_exists(self, vlan, Link.Type.PEERING, self.asys[1], self.asys[4]))
        self.assertTrue(_links_exists(self, vlan, Link.Type.PEERING, self.asys[1], self.asys[5]))

        # Reject 1-ff00:0:1 -> Owner 3
        _add_owner_policy(vlan, self.asys[1], self.owner[2], False)
        self.assertEqual(self.asys[1].accept.count(), 1)
        self.assertEqual(_count_links(self.asys[1]), 1)
        self.assertTrue(_links_exists(self, vlan, Link.Type.PEERING, self.asys[1], self.asys[5]))

        # Reject 1-ff00:0:1 -> 2-ff00:0:5
        _add_as_policy(vlan, self.asys[1], self.asys[5], False)
        self.assertEqual(self.asys[1].accept.count(), 0)
        self.assertEqual(_count_links(self.asys[1]), 0)
示例#4
0
    def CreatePolicy(self, request, context):
        """Create a new policy."""
        asn_str, client = get_client_from_metadata(
            context.invocation_metadata())
        asn = ASN(asn_str)

        if request.asn != asn_str:
            context.abort(grpc.StatusCode.PERMISSION_DENIED,
                          "Cannot create policies for other ASes")

        serializer = PolicyProtoSerializer(message=request)
        if not serializer.is_valid():
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          _fmt_validation_errors(serializer.errors))

        _assert_policy_write_permission(context, asn, client, request.vlan)

        try:
            policy = serializer.save()
        except ValidationError as e:
            msg, code = _translate_validation_errors(e)
            context.abort(code, msg)

        # Update links and notify clients
        policy_resolver.update_accepted_peers(policy.vlan, policy.asys)
        policy_resolver.update_links(policy.vlan, policy.asys)

        return serializer.message
def _add_default_policy(vlan, asys, accept):
    """Add a default policy and apply it.

    :returns: The newly created policy instance.
    """
    policy = DefaultPolicy.objects.create(vlan=vlan, asys=asys, accept=accept)
    update_accepted_peers(vlan, asys)
    update_links(vlan, asys)
    return policy
def _add_isd_policy(vlan, asys, peer_isd, accept):
    """Add an ISD peering policy and apply it.

    :returns: The newly created policy instance.
    """
    policy = IsdPeerPolicy.objects.create(vlan=vlan, asys=asys, peer_isd=peer_isd, accept=accept)
    update_accepted_peers(vlan, asys)
    update_links(vlan, asys)
    return policy
    def test_example(self):
        vlan = self.vlan[0]

        # AS-level policies
        # B accept C
        AsPeerPolicy.objects.create(vlan=vlan, asys=self.asys['B'], peer_as=self.asys['C'], accept=True)
        # C accept B, D
        AsPeerPolicy.objects.create(vlan=vlan, asys=self.asys['C'], peer_as=self.asys['B'], accept=True)
        AsPeerPolicy.objects.create(vlan=vlan, asys=self.asys['C'], peer_as=self.asys['D'], accept=True)
        # D accept C, E
        AsPeerPolicy.objects.create(vlan=vlan, asys=self.asys['D'], peer_as=self.asys['C'], accept=True)
        AsPeerPolicy.objects.create(vlan=vlan, asys=self.asys['D'], peer_as=self.asys['E'], accept=True)
        # E reject G, H
        AsPeerPolicy.objects.create(vlan=vlan, asys=self.asys['E'], peer_as=self.asys['G'], accept=False)
        AsPeerPolicy.objects.create(vlan=vlan, asys=self.asys['E'], peer_as=self.asys['H'], accept=False)

        # Owner-level policies
        # F accept [F, G]
        OwnerPeerPolicy.objects.create(vlan=vlan, asys=self.asys['F'], peer_owner=self.owner[1], accept=True)
        # G accept [F, G]
        OwnerPeerPolicy.objects.create(vlan=vlan, asys=self.asys['G'], peer_owner=self.owner[1], accept=True)

        # ISD-level policies
        # E accept ISD 2
        IsdPeerPolicy.objects.create(vlan=vlan, asys=self.asys['E'], peer_isd=self.isd[1], accept=True)
        # G accept ISD 2
        IsdPeerPolicy.objects.create(vlan=vlan, asys=self.asys['G'], peer_isd=self.isd[1], accept=True)
        # H accept ISD 2
        IsdPeerPolicy.objects.create(vlan=vlan, asys=self.asys['H'], peer_isd=self.isd[1], accept=True)

        for asys in self.asys.values():
            update_accepted_peers(vlan, asys)
        for asys in self.asys.values():
            update_links(vlan, asys)

        self.assertEqual(Link.objects.count(), 4)
        self.assertTrue(_links_exists(self, vlan, Link.Type.CORE, self.asys['B'], self.asys['C']))
        self.assertTrue(_links_exists(self, vlan, Link.Type.PEERING, self.asys['D'], self.asys['E']))
        self.assertTrue(_links_exists(self, vlan, Link.Type.PEERING, self.asys['F'], self.asys['G']))
        self.assertTrue(_links_exists(self, vlan, Link.Type.PEERING, self.asys['G'], self.asys['H']))
示例#8
0
 def delete_queryset(self, request, queryset):
     update = {(obj.vlan, obj.asys) for obj in queryset}
     super().delete_queryset(request, queryset)
     for vlan, asys in update:
         policy_resolver.update_accepted_peers(vlan, asys)
示例#9
0
 def delete_model(self, request, obj):
     super().delete_model(request, obj)
     policy_resolver.update_accepted_peers(obj.vlan, obj.asys)
示例#10
0
 def save_model(self, request, obj, form, change):
     super().save_model(request, obj, form, change)
     policy_resolver.update_accepted_peers(obj.vlan, obj.asys)
def _delete_policy(policy):
    """Delete a peering policy and apply the changes."""
    policy.delete()
    update_accepted_peers(policy.vlan, policy.asys)
    update_links(policy.vlan, policy.asys)