コード例 #1
0
def get_ptr_from_ip(ip, region_name, request_session=None) -> dict:
    params = {'ip': ip, 'region_name': region_name}
    serializer = GetPtrFromIpSerializer(data=params)
    serializer.is_valid(raise_exception=True)

    if request_session:
        designate = designate_client(api_session=IdentityAdminApi(
            request_session=request_session).session,
                                     region_name=serializer.validated_data.pop(
                                         'region_name', None))
    else:
        designate = designate_client(api_session=IdentityAdminApi().session,
                                     region_name=serializer.validated_data.pop(
                                         'region_name', None))

    related_ip = ip_address(serializer.validated_data['ip'])
    ptr_record = related_ip.reverse_pointer + '.'
    if isinstance(related_ip, IPv6Address):
        zone_name = ptr_record
    else:
        # cut the first segment (last segment from the ip)
        zone_name = ptr_record[ptr_record.index('.') + 1:]
    try:
        zones = designate.zones.list(criterion={'name': zone_name})
    except (designate_exceptions.Base, ClientException) as e:
        raise e

    if zones:
        zone_id = zones[0]['id']
        try:
            recordsets = designate.recordsets.list(zone=zone_id,
                                                   criterion={
                                                       'type': 'PTR',
                                                       'name': ptr_record
                                                   })
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to list record sets, reason {0}'.format(e))
            raise e
        if recordsets:
            # TODO(erno): returns only the first PTR entry, and the first record
            record = recordsets[0]['records'][0]
            if record.endswith('.'):
                record = record[:-1]
            return dict(
                record=record,
                zone_id=zone_id,
            )
        else:
            dict(
                record='',
                zone_id=zone_id,
            )

    return dict(
        record='',
        zone_id='',
    )
コード例 #2
0
    def create(self, request):
        """Create a dns zone"""

        if not validate_cloud_objects_limit():
            raise APIBadRequest(_('Licence cloud objects limit reached. Please check your license.'))

        serializer = DnsCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        designate = designate_client(self.identity_admin_api.session,
                                     region_name=serializer.validated_data.pop('region_name', None),
                                     sudo_project_id=serializer.validated_data.pop('sudo_project_id', None),
                                     all_projects=serializer.validated_data.pop('all_projects', None))
        serializer.validated_data.pop('client', None)
        try:
            zone = designate.zones.create(**serializer.validated_data)
        except designate_exceptions.Conflict as e:
            LOG.error('Unable to create zone, reason {0}'.format(e))
            raise ValidationError(
                {'detail': _('Unable to create zone. A zone with the same domain name already exists')}
            )
        except designate_exceptions.Base as e:
            LOG.error('Unable to create zone, reason {0}'.format(e))
            raise ValidationError({'detail': _('Unable to create zone. Please see logs for more info')})
        else:
            return Response(zone, status=HTTP_201_CREATED)
コード例 #3
0
    def update_record(self, request, pk=None):
        serializer = RecordSetAlterSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        api_session = get_api_session(request)
        designate = designate_client(api_session,
                                     region_name=serializer.validated_data.pop(
                                         'region_name', None))

        try:
            recordsets = designate.recordsets.update(
                zone=pk,
                recordset=request.data.get('pk'),
                values=serializer.validated_data)
        except (designate_exceptions.NotFound,
                designate_exceptions.ResourceNotFound) as e:
            LOG.error(e)
            raise NotFound(detail=_('Zone or record not found'))
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to update record, reason {0}'.format(e))
            raise ValidationError({
                'detail':
                _('Unable to update record. Please contact support for more info'
                  )
            })
        else:
            return Response(recordsets, status=HTTP_200_OK)
コード例 #4
0
    def list_records(self, request, pk=None):
        serializer = RecordSetListSerializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)

        api_session = get_api_session(request)
        designate = designate_client(api_session,
                                     region_name=serializer.validated_data.pop(
                                         'region_name', None))

        try:
            serializer.validated_data['sort_key'] = 'type'
            recordsets = designate.recordsets.list(
                zone=pk, criterion=serializer.validated_data)
        except (designate_exceptions.NotFound,
                designate_exceptions.ResourceNotFound) as e:
            LOG.error(e)
            raise NotFound(detail=_('Zone not found'))
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to list records, reason {0}'.format(e))
            raise ValidationError({
                'detail':
                _('Unable to list records. Please contact support for more info'
                  )
            })
        else:
            response = ListRecordsSerializer(instance=recordsets).data
            response['record_types'] = [
                x[0] for x in RECORD_TYPES if x[0] != 'SOA'
            ]
            return Response(response)
コード例 #5
0
    def list(self, request):
        """List all dns zones belonging to a region"""
        serializer = DnsFilterSerializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)

        api_session = get_api_session(request)
        designate = designate_client(api_session,
                                     region_name=serializer.validated_data.pop(
                                         'region_name', None))
        search_params, page_limit, custom_filtering_params = get_filter_params(
            request)
        criterion = {**search_params, **serializer.validated_data}

        try:
            zones = designate.zones.list(criterion=criterion, limit=page_limit)
        except (designate_exceptions.NotFound,
                designate_exceptions.ResourceNotFound) as e:
            LOG.error(e)
            raise NotFound(detail=_('No zones found'))
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to list zones, reason {0}'.format(e))
            raise ValidationError(detail=_(
                'Unable to list zones. Please contact support for more info'))
        else:
            rsp = {
                'objects':
                DnsSerializer(instance=zones, many=True).data,
                'permissions':
                permissions_cache.get_view_permissions(request.user,
                                                       self.basename),
                'hasMore':
                zones.next_page
            }
            return Response(rsp)
コード例 #6
0
    def delete_record(self, request, pk=None):
        designate = designate_client(self.identity_admin_api.session,
                                     region_name=request.query_params.get('region_name'),
                                     all_projects=request.query_params.get('all_projects'))

        try:
            recordsets = designate.recordsets.delete(zone=pk, recordset=request.query_params.get('pk'))
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to delete record, reason {0}'.format(e))
            raise ValidationError({'detail': _('Unable to delete record. Please see logs for more info')})
        else:
            return Response(recordsets, status=HTTP_204_NO_CONTENT)
コード例 #7
0
    def destroy(self, request, pk=None):
        """Delete a dns zone"""
        designate = designate_client(self.identity_admin_api.session,
                                     region_name=request.query_params.get('region_name', None),
                                     all_projects=True)

        try:
            designate.zones.delete(zone=pk)
        except designate_exceptions.Base as e:
            LOG.error('Unable to delete zone, reason {0}'.format(e))
            raise ValidationError({'detail': _('Unable to delete zone. Please see logs for more info')})
        else:
            return Response({'detail': _('Zone deleted')}, status=HTTP_204_NO_CONTENT)
コード例 #8
0
    def retrieve(self, request, pk=None):
        """Fetches a dns zone"""

        designate = designate_client(self.identity_admin_api.session,
                                     region_name=request.query_params.get('region_name', None),
                                     sudo_project_id=request.query_params.get('sudo_project_id', None),
                                     all_projects=request.query_params.get('all_projects', True))

        try:
            zone = designate.zones.get(zone=pk)
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to fetch zone, reason {0}'.format(e))
            raise ValidationError({'detail': _('Unable to fetch zone. Please see logs for more info')})
        return Response(DnsSerializer(instance=zone).data)
コード例 #9
0
    def create_records(self, request, pk=None):
        serializer = RecordSetCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        designate = designate_client(self.identity_admin_api.session,
                                     region_name=serializer.validated_data.pop('region_name', None,),
                                     sudo_project_id=serializer.validated_data.pop('sudo_project_id', None))

        try:
            records = designate.recordsets.create(zone=pk, **serializer.validated_data)
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to create record in zone {0}, reason {1}'.format(pk, e))
            raise ValidationError({'detail': _('Unable to create record. Please see logs for more info')})
        else:
            return Response(records, status=HTTP_201_CREATED)
コード例 #10
0
    def update(self, request, pk=None):
        """Updates a dns zone"""
        serializer = DnsUpdateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        designate = designate_client(self.identity_admin_api.session,
                                     region_name=serializer.validated_data.pop('region_name', None),
                                     sudo_project_id=serializer.validated_data.pop('sudo_project_id', None),
                                     all_projects=serializer.validated_data.pop('all_projects', None))

        try:
            zone = designate.zones.update(zone=pk, values=serializer.validated_data)
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to update zone, reason {0}'.format(e))
            raise ValidationError({'detail': e})
        else:
            return Response(zone, status=HTTP_200_OK)
コード例 #11
0
    def update_record(self, request, pk=None):
        serializer = RecordSetUpdateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        designate = designate_client(self.identity_admin_api.session,
                                     region_name=serializer.validated_data.pop('region_name', None),
                                     all_projects=serializer.validated_data.pop('all_projects', None))

        try:
            recordsets = designate.recordsets.update(zone=pk,
                                                     recordset=request.data.get('pk'),
                                                     values=serializer.validated_data)
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to update record, reason {0}'.format(e))
            raise ValidationError({'detail': _('Unable to update record. Please see longs for more info')})
        else:
            return Response(recordsets, status=HTTP_200_OK)
コード例 #12
0
    def list(self, request):
        """List all dns zones belonging to a region"""

        serializer = DnsFilterSerializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)

        search_params, page_limit, custom_filtering_params = get_filter_params(request)
        all_projects = serializer.validated_data.pop('all_projects', None)

        # custom filtering by client
        custom_api_session = None
        client_id = custom_filtering_params.get('client', None) if custom_filtering_params else None
        if client_id:
            client = Client.objects.get(id=client_id)
            project = client.first_project
            if not project:
                raise APIBadRequest(_('Client you want zones for does not have an openstack project.'))
            custom_api_session = IdentityUserApi(
                project.project_id,
                project.project_domain_id,
                cache=request.session
            ).session
            all_projects = None

        designate = designate_client(self.identity_admin_api.session if not custom_api_session else custom_api_session,
                                     region_name=serializer.validated_data.pop('region_name', None),
                                     sudo_project_id=serializer.validated_data.pop('sudo_project_id', None),
                                     all_projects=all_projects)
        criterion = {**search_params, **serializer.validated_data}

        try:
            zones = designate.zones.list(criterion=criterion, limit=page_limit)
        except (designate_exceptions.NotFound, designate_exceptions.ResourceNotFound) as e:
            LOG.error(e)
            raise NotFound(detail=_('No zones found'))
        except designate_exceptions.Base as e:
            LOG.error('Unable to list zones, reason {0}'.format(e))
            raise ValidationError({'detail': _('Unable to list zones. Please see logs for more info')})
        except EndpointNotFound as e:
            LOG.error('Endpoint not found: {}'.format(e))
            raise NotFound(detail=_('DSN endpoint not found'))
        else:
            rsp = {'objects': DnsSerializer(instance=zones, many=True).data,
                   'count': len(zones),
                   'hasMore': zones.next_page}
            return Response(rsp)
コード例 #13
0
    def retrieve(self, request, pk=None):
        """Fetches a dns zone"""
        api_session = get_api_session(request)
        designate = designate_client(api_session,
                                     region_name=request.query_params.get(
                                         'region_name', None))

        try:
            zone = designate.zones.get(zone=pk)
        except (designate_exceptions.NotFound,
                designate_exceptions.ResourceNotFound) as e:
            LOG.error(e)
            raise NotFound(detail=_('Zone not found'))
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to fetch zone, reason {0}'.format(e))
            raise ValidationError(detail=_(
                'Unable to fetch zone. Please contact support for more info'))

        return Response(DnsSerializer(instance=zone).data)
コード例 #14
0
    def create_records(self, request, pk=None):
        serializer = RecordSetCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        api_session = get_api_session(request)
        designate = designate_client(api_session,
                                     region_name=serializer.validated_data.pop(
                                         'region_name', None))

        try:
            records = designate.recordsets.create(zone=pk,
                                                  **serializer.validated_data)
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to create record in zone {0}, reason {1}'.format(
                pk, e))
            raise ValidationError(detail=_(
                'Unable to create record. Please contact support for more info'
            ))
        else:
            return Response(records, status=HTTP_201_CREATED)
コード例 #15
0
    def delete_record(self, request, pk=None):
        api_session = get_api_session(request)
        designate = designate_client(
            api_session, region_name=request.data.get('region_name'))

        try:
            recordsets = designate.recordsets.delete(
                zone=pk, recordset=request.data.get('pk'))
        except (designate_exceptions.NotFound,
                designate_exceptions.ResourceNotFound) as e:
            LOG.error(e)
            raise NotFound(detail=_('Record not found'))
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to delete record, reason {0}'.format(e))
            raise ValidationError({
                'detail':
                _('Unable to delete record. Please contact support for more info'
                  )
            })
        else:
            return Response(recordsets, status=HTTP_204_NO_CONTENT)
コード例 #16
0
    def create(self, request):
        """Create a dns zone"""

        if not validate_cloud_objects_limit():
            raise APIBadRequest(
                _('Failed to create DNS zone. Please contact support.'))

        serializer = DnsCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        api_session = get_api_session(request)
        designate = designate_client(api_session,
                                     region_name=serializer.validated_data.pop(
                                         'region_name', None))

        try:
            zone = designate.zones.create(**serializer.validated_data)
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to create zone, reason {0}'.format(e))
            raise ValidationError({'detail': e})
        else:
            return Response(zone, status=HTTP_201_CREATED)
コード例 #17
0
    def list_records(self, request, pk=None):
        serializer = RecordSetListSerializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)
        recordset_default_limit = getattr(settings, 'OPENSTACK_DESIGNATE_RECORDSET_LIMIT', 100000)
        records_limit = serializer.validated_data.pop('limit', recordset_default_limit)

        designate = designate_client(self.identity_admin_api.session,
                                     region_name=serializer.validated_data.pop('region_name', None),
                                     all_projects=serializer.validated_data.pop('all_projects', None))

        try:
            serializer.validated_data['sort_key'] = 'type'
            recordsets = designate.recordsets.list(zone=pk, criterion=serializer.validated_data, limit=records_limit)
        except (designate_exceptions.NotFound, designate_exceptions.ResourceNotFound) as e:
            LOG.error(e)
            raise NotFound(detail=_('Zone not found'))
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to list records, reason {0}'.format(e))
            raise ValidationError({'detail': str(e)})
        else:
            response = ListRecordsSerializer(instance=recordsets).data
            response['record_types'] = [x[0] for x in RECORD_TYPES if x[0] != 'SOA']
            return Response(response)
コード例 #18
0
    def update(self, request, pk=None):
        """Updates a dns zone"""

        serializer = DnsUpdateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        api_session = get_api_session(request)
        designate = designate_client(api_session,
                                     region_name=serializer.validated_data.pop(
                                         'region_name', None))

        try:
            zone = designate.zones.update(zone=pk,
                                          values=serializer.validated_data)
        except (designate_exceptions.NotFound,
                designate_exceptions.ResourceNotFound) as e:
            LOG.error(e)
            raise NotFound(detail=_('Zone not found'))
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to update zone, reason {0}'.format(e))
            raise ValidationError({'detail': e})
        else:
            return Response(zone, status=HTTP_200_OK)
コード例 #19
0
    def destroy(self, request, pk=None):
        """Delete a dns zone"""

        api_session = get_api_session(request)
        designate = designate_client(api_session,
                                     region_name=request.query_params.get(
                                         'region_name', None))

        try:
            designate.zones.delete(zone=pk)
        except (designate_exceptions.NotFound,
                designate_exceptions.ResourceNotFound) as e:
            LOG.error(e)
            raise NotFound(detail=_('Zone not found'))
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to delete zone, reason {0}'.format(e))
            raise ValidationError({
                'detail':
                _('Unable to delete zone. Please contact support for more info'
                  )
            })
        else:
            return Response({'detail': _('Zone deleted')},
                            status=HTTP_204_NO_CONTENT)
コード例 #20
0
def create_or_update_ptr(ip, record, region_name, zone_id=None, request=None):
    data = dict(
        ip=ip,
        record=record,
        region_name=region_name,
    )
    if zone_id:
        data['zone_id'] = zone_id
    serializer = CreateOrUpdatePtrSerializer(data=data)
    serializer.is_valid(raise_exception=True)

    if request:
        designate = designate_client(api_session=IdentityAdminApi(
            request_session=request.session).session,
                                     region_name=serializer.validated_data.pop(
                                         'region_name', None))
    else:
        designate = designate_client(api_session=IdentityAdminApi().session,
                                     region_name=serializer.validated_data.pop(
                                         'region_name', None))

    try:
        zone_id, created = get_or_create_zone(designate=designate,
                                              request=request,
                                              data=data)
    except (designate_exceptions.Base, designate_exceptions.RemoteError) as e:
        raise e

    record = serializer.validated_data['record']
    if not record.endswith('.'):
        record += '.'

    # update or create PTR record
    if created:
        recordset_name = ip_address(
            serializer.validated_data['ip']).reverse_pointer + '.'
        try:
            record = designate.recordsets.create(zone=zone_id,
                                                 records=[record],
                                                 name=recordset_name,
                                                 type_='PTR')
        except (designate_exceptions.BadRequest, ClientException) as e:
            raise e
    else:
        try:
            ptr_record = ip_address(
                serializer.validated_data['ip']).reverse_pointer + '.'
            recordsets = designate.recordsets.list(zone=zone_id,
                                                   criterion={
                                                       'type': 'PTR',
                                                       'name': ptr_record
                                                   })
        except designate_exceptions.Base as e:
            LOG.error('Unable to list record sets, reason {0}'.format(e))
            raise e
        try:
            if recordsets:
                record = designate.recordsets.update(
                    zone=zone_id,
                    recordset=recordsets[0]['id'],
                    values={'records': [record]})
            else:
                recordset_name = ip_address(
                    serializer.validated_data['ip']).reverse_pointer + '.'
                record = designate.recordsets.create(zone=zone_id,
                                                     records=[record],
                                                     name=recordset_name,
                                                     type_='PTR')
        except (designate_exceptions.BadRequest, ClientException,
                designate_exceptions.Conflict) as e:
            raise e

    return dict(record=record)
コード例 #21
0
    def synchronize_records(self, request, pk):
        serializer = SyncRecordSetsSerializer(data=request.data, many=True)
        serializer.is_valid(raise_exception=True)
        current_recordsets = serializer.validated_data
        for recordset_i in current_recordsets:
            for recordset_j in current_recordsets:
                if recordset_i['id'] == recordset_j['id']:
                    continue
                if recordset_i['name'] == recordset_j['name'] and recordset_i['type'] == recordset_j['type']:
                    raise ValidationError({'detail': _('More than one recordset exists with the same subdomain '
                                                       '{subd} and type {type} exist'
                                                       .format(subd=recordset_i['name'], type=recordset_i['type']))})

        designate = designate_client(self.identity_admin_api.session, all_projects=True, edit_managed=True)

        try:
            recordset_default_limit = getattr(settings, 'OPENSTACK_DESIGNATE_RECORDSET_LIMIT', 100000)
            existing_recordsets = designate.recordsets.list(zone=pk, limit=recordset_default_limit)
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to list records, reason {0}'.format(e))
            raise ValidationError({'detail': _('Unable to list records. Please contact support for more info')})

        # create, update and delete recordsets
        create_recordsets, update_recordsets, delete_recordsets = \
            get_recordsets_changes(current_recordsets, existing_recordsets)

        # TODO(erno): make a celery task for this, refactor frontend too
        errors = {}
        create_errors = ''
        for recordset in create_recordsets:
            try:
                designate.recordsets.create(zone=pk, name=recordset['name'], type_=recordset['type'],
                                            records=recordset['records'], ttl=recordset['ttl'])
            except (designate_exceptions.Base, ClientException) as e:
                create_errors += '{}\n'.format(remove_unicode(str(e)))
        if create_errors:
            errors['detail'] = create_errors

        for recordset in update_recordsets:
            try:
                designate.recordsets.update(zone=pk, recordset=recordset['id'],
                                            values={'records': recordset['records'], 'ttl': recordset['ttl']})
            except (designate_exceptions.Base, ClientException) as e:
                errors[recordset['id']] = remove_unicode(str(e))

        for record_id in delete_recordsets:
            try:
                designate.recordsets.delete(zone=pk, recordset=record_id)
            except (designate_exceptions.Base, ClientException) as e:
                errors[record_id] = remove_unicode(str(e))

        if errors:
            raise ValidationError(errors)

        try:
            recordsets = designate.recordsets.list(zone=pk)
        except (designate_exceptions.Base, ClientException) as e:
            LOG.error('Unable to list records, reason {0}'.format(e))
            raise ValidationError({'detail': str(e)})
        else:
            response = ListRecordsSerializer(instance=recordsets).data
            response['record_types'] = [x[0] for x in RECORD_TYPES if x[0] != 'SOA']
            response['detail'] = _('Recordsets update scheduled')
            return Response(response)