Example #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()
Example #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
Example #3
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']))
Example #7
0
    def SetPortRange(self, request, context):
        """Set the UDP port range used for SCION underlay connections."""
        asn_str, _ = get_client_from_metadata(context.invocation_metadata())
        asn = ASN(asn_str)

        # Validate arguments and retrieve the interface
        try:
            vlan = VLAN.objects.get(name=request.interface_vlan)
        except VLAN.DoesNotExist:
            context.abort(grpc.StatusCode.NOT_FOUND, "VLAN does not exist")
        try:
            ip = ipaddress.ip_address(request.interface_ip)
        except ValueError:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          "Invalid IP address")
        try:
            interface = Interface.objects.get(vlan=vlan, public_ip=ip)
        except (Interface.DoesNotExist, Interface.MultipleObjectsReturned):
            context.abort(grpc.StatusCode.NOT_FOUND, "Interface not found")

        recreate_links = not (request.first_port <= interface.first_port
                              and request.last_port >= interface.last_port)

        try:
            interface.first_port = request.first_port
            interface.last_port = request.last_port
            interface.save()
        except ValidationError:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          "Invalid port range")

        if recreate_links:
            # Recreate the interface's links with the new ports
            for link in interface.query_links().all():
                link.delete()
            policy_resolver.update_links(vlan, AS.objects.get(asn=asn))

        return peering_pb2.google_dot_protobuf_dot_empty__pb2.Empty()
Example #8
0
def update_links(modeladmin, request, queryset):
    for iface in queryset.all():
        policy_resolver.update_links(iface.vlan, iface.peering_client.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)