Ejemplo n.º 1
0
def check_reference(resource, attrs):
    #
    # Reference check for VPNBind records
    #
    # If a IPsecEnforcer is using a VPNBind record, then the VPNBind should not
    # be allowed to be deleted.
    if resource in VPN_BIND:
        relation = RESOURCE_TO_RELATION_MAP[resource]
        # Find the VPNEndpoint/Peer-VPNEndpoint field names
        vpnendpoint_field, peer_vpnendpoint_field = get_vpnendpoints_field(
            relation)

        # Get the list of IPsecEnforcers
        ipsecenforcers = (
            IPsecEnforcerInfo().get_vpnendpoint_to_ipsecenforcer_and_fqdn_list(
                attrs[vpnendpoint_field]))

        peer_ipsecenforcers = (
            IPsecEnforcerInfo().get_vpnendpoint_to_ipsecenforcer_and_fqdn_list(
                attrs[peer_vpnendpoint_field]))

        if ipsecenforcers or peer_ipsecenforcers:
            raise serializers.ValidationError("Resource can not be deleted. "
                                              "The resource configuration is "
                                              "in use by IPsecEnforcer(s)")

    #
    # Reference check for Non-VPNBind records
    #
    dependencies = RESOURCE_DEPENDENCY_MAP.get(resource, None)

    if dependencies is None:
        return

    resources = dependencies[0]
    relations = [RESOURCE_TO_RELATION_MAP[relation] for relation in resources]

    fields = RESOURCE_DEPENDENCY_MAP[resource][1:]

    reference_exists = False
    for relation, field in itertools.product(relations, fields):
        value = attrs.get('id', None)
        if value is not None:
            records = storage.plugin.get_records(relation)
            for record in records:
                if record[field] == str(attrs['id']):
                    reference_exists = True
                    break

        if reference_exists:
            raise serializers.ValidationError("Resource can not be deleted. "
                                              "{0} with id {1} is in "
                                              "use".format(
                                                  resource, str(value)))
Ejemplo n.º 2
0
def ipsec_enforcer_registration(request, version, namespace, pk='None'):
    """Create, list(one or all), update or delete resource.

    Args:
        version (str): API version
        namespace (str): Tenant name
        request (HttpRequest): Complete HTTP request with header and
            body
        pk (str): Primary Key of Record. Defaults to 'None'.

    Note: version and namespace is currently not used. It is for future
        support of multiple API versions and multi tenants.

    Returns:
        HTTPResponse with data/error and status code.
    """
    # Retrieve record(s) to be used by later operations(except POST)
    # pk = 'None' means retrieve all records
    if request.method != 'POST':
        try:
            record = IPsecEnforcerRegistration.get(id=pk)
        except ResourceNotFound:
            raise NotFound(
                detail=("Resource {0} with id {1} not "
                        "found").format(IPsecEnforcerRegistration, pk))

    # Get the record with id 'pk'
    if request.method == 'GET':
        policy = IPsecEnforcerConfig().prepare_ipsec_enforcer_config(pk)
        return Response(policy, status=status.HTTP_200_OK)

    # Create and store a record
    if request.method == 'POST':
        data = JSONParser().parse(request)
        serializer = IPsecEnforcerRegistrationSerializer(
            data=data, context={'resource_name': 'IPsecEnforcerRegistration'})
        if serializer.is_valid():
            serializer.save()
            IPsecEnforcerNotification.client_ipsecenforcer_register(
                serializer.data['id'])
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            serializer.log_invalid()
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

    # Delete the record with id 'pk'
    if request.method == 'DELETE':
        # Before de-registration(deletion), fetch all the VPNEndpoint(s)
        # associated with IPsecEnforcer
        mapping_records = (
            IPsecEnforcerInfo.get_ipsecenforcer_to_vpnendpoint_map(record.id))

        # Delete the record
        record.delete()

        # Notify the peer IPsecEnforcer(s)
        IPsecEnforcerNotification.client_ipsecenforcer_deregister(
            record.id, mapping_records)
        return HttpResponse(status=status.HTTP_204_NO_CONTENT)
Ejemplo n.º 3
0
    def client_ipsecenforcer_register(cls, ipsecenforcer_id):
        """IPC Client for IPsecEnforcer Registration

        Args:
            ipsecenforcer_id: id of IPsecEnforcer
        """
        try:
            client = Client((cls.process_fqdn, cls.process_port))
        except socket_error:
            return

        mapping_records = (
            IPsecEnforcerInfo.get_ipsecenforcer_to_vpnendpoint_map(
                    ipsecenforcer_id)
        )

        notification_message = {
            'notification_type': 'REGISTRATION',
            'ipsecenforcer_id': ipsecenforcer_id,
            'mapping_records': mapping_records
        }

        # Send the notification_message to the IPsecEnforcer Notification
        # listener
        try:
            client.send(notification_message)
        except socket_error:
            return
    def _add_config_version(self, ipsecenforcer_id):
        """Add config version

        Args:
            ipsecenforcer_id (str): id of IPsecEnforcer
        """
        config_version = (IPsecEnforcerInfo(
        ).increment_ipsecenforcer_config_version(ipsecenforcer_id))

        self.ipsecenforcer_config.update({'version': config_version})
Ejemplo n.º 5
0
    def save(self):
        """Write the record in the storage backend

        Returns:
            self (Resource): Return the object itself

        Raises:
            TypeError: When error storing the resource in backend
        """
        try:
            IPsecEnforcerInfo().register_ipsecenforcer(self)
            return self
        except TypeError:
            LOG.error(
                _("Error in storing data for %s with id %s" %
                  (self.resource_name, self.id)))
            raise
        finally:
            IPsecEnforcerInfo().delete_ipsecenforcer_to_vpnendpoint_map(
                self.id, temp=True)
Ejemplo n.º 6
0
    def notify_ipsecenforcers_of_vpnendpoint(cls, vpnendpoint_id):
        """Notify all the IPsecEnforcer(s) of the VPNEndpoint record

        Args:
            vpnendpoint_id (str): ID of VPNEndpoint record
        """
        # Fetch all the  IPsecEnforcers that belong to VPNEndpoint record
        ipsecenforcers_fqdn_id = (IPsecEnforcerInfo(
        ).get_vpnendpoint_to_ipsecenforcer_and_fqdn_list(vpnendpoint_id))

        # Remove duplicates to make sure that each IPsecEnforcer will receive a
        # single notification
        ipsecenforcers_fqdn_id = {
            v['fqdn']: v
            for v in ipsecenforcers_fqdn_id
        }.values()
        map(cls.notify_ipsecenforcers, ipsecenforcers_fqdn_id)
    def _add_fqdn_list_of_vpnendpoint(self, vpnendpoint_id):
        """Add FQDN of Peer VPNEndpoint to the configuration policy

        Args:
            vpnendpoint_id (str): id of VPNEndpointgroup

        Returns:
            list : List of FQDN for VPNEndpoint
        """
        records = (IPsecEnforcerInfo(
        ).get_vpnendpoint_to_ipsecenforcer_and_fqdn_list(vpnendpoint_id))

        fqdn_list = [record['fqdn_tunnel'] for record in records]

        if fqdn_list:
            self.ipsecenforcer_config['fqdn_list'].update(
                {vpnendpoint_id: fqdn_list})

        return fqdn_list
Ejemplo n.º 8
0
    def validate(self, attrs):
        """Check that the endpoint_name is valid"""
        endpoint_name = attrs['endpoint_name']
        endpoint_type = attrs['endpoint_type']

        if len(endpoint_name) != len(set(endpoint_name)):
            raise serializers.ValidationError(
                _("Duplicates are not allowed in "
                  "the list of endpoint_name"))

        if len(endpoint_name) != len(endpoint_type):
            raise serializers.ValidationError(
                _("Number of entries in the list "
                  "of endpoint_type and "
                  "endpoint_name should be same"))

        for endpoint_name, endpoint_type in izip_longest(
                endpoint_name, endpoint_type):
            if endpoint_type == 'group':
                record = storage.plugin.get_records_by_secondary_index(
                    'vpnendpointgroups', 'name', endpoint_name)
            elif endpoint_type == 'localsite':
                record = storage.plugin.get_records_by_secondary_index(
                    'vpnendpointlocalsites', 'name', endpoint_name)
            elif endpoint_type == 'remotesite':
                record = storage.plugin.get_records_by_secondary_index(
                    'vpnendpointremotesites', 'name', endpoint_name)

            if (record is None) or (not record):
                raise serializers.ValidationError(
                    ("endpoint_name {0} is not "
                     "a valid endpoint_type "
                     "{1}").format(endpoint_name, endpoint_type))
            else:
                IPsecEnforcerInfo().put_ipsecenforcer_to_vpnendpoint_map(
                    attrs['id'], {
                        'endpoint_id': record[0]['id'],
                        'endpoint_type': endpoint_type
                    },
                    temp=True)

        return attrs
    def _add_psk(self, vpnbind_id, psk, peer_vpnendpoint_id, fqdn, peer):
        """Add PSK(Pre-Shared Key)

        Args:
            vpnbind_id (str): id of VPNBind record
            psk (str): PSK provided with the VPNBind record
            peer_vpnendpoint_id (str): id of peer VPNEndpoint
            fqdn (str): FQDN of IPsecEnforcer Tunnel Interface
            peer (bool): True, If IPsecEnforcer belongs to peer
                VPNEndpoint or Else False.
        """
        records = (IPsecEnforcerInfo(
        ).get_vpnendpoint_to_ipsecenforcer_and_fqdn_list(peer_vpnendpoint_id))

        fqdn_list = [record['fqdn_tunnel'] for record in records]

        if peer:
            fqdn_pairs = itertools.product([fqdn], fqdn_list)
        else:
            fqdn_pairs = itertools.product(fqdn_list, [fqdn])

        fqdn_pair_with_psk = self._generate_psk(vpnbind_id, fqdn_pairs, psk)

        self.ipsecenforcer_config['fqdn_pair_psk'].update(fqdn_pair_with_psk)
Ejemplo n.º 10
0
 def delete(self):
     IPsecEnforcerInfo().deregister_ipsecenforcer(self)
    def prepare_ipsec_enforcer_config(self, ipsecenforcer_id):
        """Prepare VPN configuration for IPsecEnforcer

        Args:
            ipsecenforcer_id (str) : id of IPsecEnforcer

        Returns:
            dict : IPsecEnforcer VPN Configuration
        """
        # Reset the ipsecenforcer_config
        for key in self.ipsecenforcer_config.iterkeys():
            self.ipsecenforcer_config[key].clear()

        # Fetch the IPsecEnforcer record
        ipsec_enforcer_record = storage.plugin.get_record(
            'ipsec_enforcer_registrations', ipsecenforcer_id)

        # Fetch the VPNEndpoint(s) corresponding to the IPsecEnforcer
        mapping_records = (
            IPsecEnforcerInfo.get_ipsecenforcer_to_vpnendpoint_map(
                ipsecenforcer_id))

        for mapping_record in mapping_records:

            if mapping_record['endpoint_type'] == 'group':

                LOG.debug(
                    _("Preparing VPN configurations for IPsecEnforcer id "
                      "%(ipsecenforcer_id)s with vpnendpointgroup id "
                      "%(vpnendpoint_id)s") % {
                          'ipsecenforcer_id': ipsecenforcer_id,
                          'vpnendpoint_id': mapping_record['endpoint_id']
                      })

                endpoint_record = storage.plugin.get_record(
                    RESOURCE_TO_RELATION_MAP['VPNEndpointGroup'],
                    mapping_record['endpoint_id'])

                self.process_vpnbind_config(ipsec_enforcer_record,
                                            VPN_BIND_GROUP,
                                            endpoint_record['id'])

            elif mapping_record['endpoint_type'] == 'localsite':

                LOG.debug(
                    _("Preparing VPN configurations for IPsecEnforcer id "
                      "%(ipsecenforcer_id)s with vpnendpointlocalsite id "
                      "%(vpnendpoint_id)s") % {
                          'ipsecenforcer_id': ipsecenforcer_id,
                          'vpnendpoint_id': mapping_record['endpoint_id']
                      })

                endpoint_record = storage.plugin.get_record(
                    RESOURCE_TO_RELATION_MAP['VPNEndpointLocalSite'],
                    mapping_record['endpoint_id'])

                self.process_vpnbind_config(ipsec_enforcer_record,
                                            VPN_BIND_LOCALSITE,
                                            endpoint_record['id'])

            elif mapping_record['endpoint_type'] == 'remotesite':

                LOG.debug(
                    _("Preparing VPN configurations for IPsecEnforcer id "
                      "%(ipsecenforcer_id)s with vpnendpointremotesite "
                      "id %(vpnendpoint_id)s") % {
                          'ipsecenforcer_id': ipsecenforcer_id,
                          'vpnendpoint_id': mapping_record['endpoint_id']
                      })

                endpoint_record = storage.plugin.get_record(
                    RESOURCE_TO_RELATION_MAP['VPNEndpointRemoteSite'],
                    mapping_record['endpoint_id'])

                self.process_vpnbind_config(ipsec_enforcer_record,
                                            VPN_BIND_REMOTESITE,
                                            endpoint_record['id'])

        if mapping_records:
            self._add_config_version(ipsecenforcer_id)

        return self.ipsecenforcer_config