Beispiel #1
0
def test_create_zone(cloud):
    """
    Unit test for creating a new DNS zone.
    """
    global __zone_id__
    global __num_zones__

    kwargs = {}
    kwargs['domain'] = 'domain.com'
    kwargs['type'] = 'master'
    kwargs['ttl'] = 172800
    kwargs['extra'] = {}

    __num_zones__ = len(Zone.objects(cloud=cloud))
    print "Zones initially %d" % __num_zones__
    print "**** Create DNS zone with domain %s" % kwargs['domain']
    Zone.add(owner=cloud.owner, cloud=cloud, id='', **kwargs)

    zones = Zone.objects()
    for zone in zones:
        if zone.domain == 'domain.com.':
            __zone_id__ = zone.id
            break

    if __zone_id__:
        if __num_zones__ == len(Zone.objects(cloud=cloud)) - 1:
            print "**DNS zone created succesfully on the provider and the DB"
            __num_zones__ += 1
            print "__num_zones__: %d" % __num_zones__
        else:
            raise Exception
Beispiel #2
0
def create_dns_zone(request):
    """
    Create a new DNS zone under a specific cloud.
    ---
    """
    auth_context = auth_context_from_request(request)

    cloud_id = request.matchdict['cloud']
    auth_context.check_perm("cloud", "read", cloud_id)
    auth_context.check_perm("cloud", "create_resources", cloud_id)
    tags = auth_context.check_perm("zone", "add", None)
    # Try to get the specific cloud for which we will create the zone.
    try:
        cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id)
    except me.DoesNotExist:
        raise CloudNotFoundError

    params = params_from_request(request)
    new_zone = Zone.add(owner=cloud.owner, cloud=cloud, **params).as_dict()

    if tags:
        resolve_id_and_set_tags(auth_context.owner,
                                'zone',
                                new_zone['id'],
                                tags,
                                cloud_id=cloud_id)

    # Schedule a UI update
    trigger_session_update(auth_context.owner, ['zones'])
    return new_zone
Beispiel #3
0
    def find_best_matching_zone(owner, name):
        """
        This is a static method that tries to extract a valid domain from
        the name provided, trying to find the best matching DNS zone. This only
        works with 'A', 'AAAA' and 'CNAME' type records.
        This is common for all providers, there's no need to override this.
        ---
        """
        # TODO: Adding here for circular dependency issue. Need to fix this.
        from mist.api.dns.models import Zone

        # Split hostname in dot separated parts.
        parts = [part for part in name.split('.') if part]
        # Find all possible domains for this domain name,
        # longest first
        all_domains = {}
        for i in range(1, len(parts) - 1):
            subdomain = '.'.join(parts[:i])
            domain = '.'.join(parts[i:]) + '.'
            all_domains[domain] = subdomain
        if not all_domains:
            raise BadRequestError("Couldn't extract a valid domain from "
                                  "the provided '%s'." % name)

        zones = Zone.objects(owner=owner)
        # We need to iterate over all the cloud DNS zones to find
        # any that is matching based on the domain. If one is found
        # then create an "A" type record with the provided name.
        for zone_candidate in zones:
            for domain, subdomain in all_domains.iteritems():
                if zone_candidate.domain == domain:
                    return zone_candidate
        raise BadRequestError("No DNS zone found, can't proceed with "
                              "creating record '%s'." % name)
Beispiel #4
0
def create_dns_zone(request):
    """
    Tags: dns
    ---
    Creates a new DNS zone under the given cloud.
    CREATE_RESOURCES permission required on cloud.
    ADD permission required on zone.
    ---
    cloud:
      in: path
      required: true
      type: string
    """
    auth_context = auth_context_from_request(request)

    cloud_id = request.matchdict['cloud']
    auth_context.check_perm("cloud", "read", cloud_id)
    auth_context.check_perm("cloud", "create_resources", cloud_id)
    tags, _ = auth_context.check_perm("zone", "add", None)

    try:
        cloud = Cloud.objects.get(owner=auth_context.owner, id=cloud_id)
    except me.DoesNotExist:
        raise CloudNotFoundError

    params = params_from_request(request)
    new_zone = Zone.add(owner=cloud.owner, cloud=cloud, **params)
    new_zone.assign_to(auth_context.user)

    if tags:
        resolve_id_and_set_tags(auth_context.owner, 'zone', new_zone.id,
                                tags, cloud_id=cloud_id)

    return new_zone.as_dict()
Beispiel #5
0
 def list_cached_zones(self):
     """Returns zones stored in database
     for a specific cloud
     """
     # FIXME: Move these imports to the top of the file when circular
     # import issues are resolved
     from mist.api.dns.models import Zone
     return Zone.objects(cloud=self.cloud, deleted=None)
Beispiel #6
0
def test_list_zones(cloud, load_staging_l_zones):
    """
    Testing listing DNS zones
    """

    global __zone_id__
    global __num_zones__

    response = cloud.ctl.dns.list_zones()
    __num_zones__ = len(Zone.objects(cloud=cloud))
    print "Num zones response: %d" % len(response)
    if len(response) == __num_zones__:
        print "Success, we have %d zones" % len(response)
    else:
        raise Exception
Beispiel #7
0
def create_zone(create_zone_request=None):  # noqa: E501
    """Create zone

    Creates one or more zones on the specified cloud. If async is true, a jobId will be returned. READ permission required on cloud. CREATE_RESOURCES permission required on cloud. CREATE permission required on zone. # noqa: E501

    :param create_zone_request:
    :type create_zone_request: dict | bytes

    :rtype: CreateZoneResponse
    """
    from mist.api.methods import list_resources
    if connexion.request.is_json:
        create_zone_request = CreateZoneRequest.from_dict(connexion.request.get_json())  # noqa: E501
    try:
        auth_context = connexion.context['token_info']['auth_context']
    except KeyError:
        return 'Authentication failed', 401
    params = delete_none(create_zone_request.to_dict())
    try:
        [cloud], total = list_resources(
            auth_context, 'cloud', search=params.pop('cloud'), limit=1)
    except ValueError:
        return 'Cloud does not exist', 404
    try:
        auth_context.check_perm("cloud", "read", cloud.id)
        auth_context.check_perm("cloud", "create_resources", cloud.id)
        tags, _ = auth_context.check_perm("zone", "add", None)
    except PolicyUnauthorizedError:
        return 'You are not authorized to perform this action', 403
    params['domain'] = params.pop('name')
    try:
        new_zone = Zone.add(owner=cloud.owner, cloud=cloud, **params)
    except BadRequestError as e:
        return str(e), 400
    except CloudUnauthorizedError:
        return 'You are not authorized to perform this action', 403
    except ZoneCreationError as e:
        return str(e), 503
    except ZoneListingError as e:
        return str(e), 503
    except CloudUnavailableError as e:
        return str(e), 503
    new_zone.assign_to(auth_context.user)
    if tags:
        resolve_id_and_set_tags(auth_context.owner, 'zone', new_zone.id,
                                tags, cloud_id=cloud.id)
    return new_zone.as_dict()
Beispiel #8
0
def test_list_records(cloud, load_staging_l_records):
    """
    Testing listing DNS records
    """
    global __zone_id__
    global __num_records__
    # zone = Zone.objects.get(owner=cloud.owner, id=__zone_id__)

    # records = zone.ctl.list_records()
    # print len(records)

    # if len(records) == __num_records__ + 2:
    #     print "List Records success"
    # else:
    #     raise Exception

    zones = Zone.objects(owner=cloud.owner)
    for zone in zones:
        records = zone.ctl.list_records()
        for record in records:
            print record.as_dict()
Beispiel #9
0
def test_delete_record(cloud):
    """
    Testing deleting a particular records from a DNS zone
    """
    global __zone_id__
    global __record_id__
    # zone = Zone.objects.get(owner=cloud.owner, id=__zone_id__)
    # record = Record.objects.get(id=__record_id__)
    # try:
    #     record.ctl.delete_record()
    # except Exception:
    #     print "can't delete record: %s" % record.record_id
    # print "**** Record deleted successfully"

    zones = Zone.objects(owner=cloud.owner)
    print "We got %d zones" % len(zones)
    for zone in zones:
        records = Record.objects(zone=zone, type='A')
        for record in records:
            try:
                record.ctl.delete_record()
            except Exception:
                print "can't delete record: %s" % record.record_id
            print "**** Record deleted successfully"
Beispiel #10
0
    def list_zones(self):
        """
        This is the public method to call when requesting all the DNS zones
        under a specific cloud.
        """

        # TODO: Adding here for circular dependency issue. Need to fix this.
        from mist.api.dns.models import Zone

        # Fetch zones from libcloud connection.
        pr_zones = self._list_zones__fetch_zones()

        zones = []
        new_zones = []
        for pr_zone in pr_zones:
            # FIXME: We are using the zone_id and owner instead of the
            # cloud_id to search for existing zones because providers
            # allow access to the same zone from multiple clouds so
            # we can end up adding the same zone many times under
            # different clouds.
            try:
                zones_q = Zone.objects(owner=self.cloud.owner,
                                       zone_id=pr_zone.id,
                                       deleted=None)
                for zone in zones_q:
                    if zone.cloud.ctl.provider == self.cloud.ctl.provider:
                        break
                else:
                    raise Zone.DoesNotExist
            except Zone.DoesNotExist:
                log.info("Zone: %s/domain: %s not in the database, creating.",
                         pr_zone.id, pr_zone.domain)
                zone = Zone(cloud=self.cloud,
                            owner=self.cloud.owner,
                            zone_id=pr_zone.id)
                new_zones.append(zone)
            zone.domain = pr_zone.domain
            zone.type = pr_zone.type
            zone.ttl = pr_zone.ttl
            zone.extra = pr_zone.extra
            try:
                zone.save()
            except me.ValidationError as exc:
                log.error("Error updating %s: %s", zone, exc.to_dict())
                raise BadRequestError({
                    'msg': exc.message,
                    'errors': exc.to_dict()
                })
            except me.NotUniqueError as exc:
                log.error("Zone %s not unique error: %s", zone, exc)
                raise ZoneExistsError()
            zones.append(zone)
        self.cloud.owner.mapper.update(new_zones)

        # Delete any zones in the DB that were not returned by the provider
        # meaning they were deleted otherwise.
        Zone.objects(
            cloud=self.cloud, id__nin=[z.id for z in zones],
            deleted=None).update(set__deleted=datetime.datetime.utcnow())

        # Format zone information.
        return zones
Beispiel #11
0
    def _list_zones(self):
        """
        Requesting all the DNS zones
        under a specific cloud.
        """
        from mist.api.dns.models import Zone

        # Fetch zones from libcloud connection.
        pr_zones = self._list_zones__fetch_zones()

        zones = []
        new_zones = []
        for pr_zone in pr_zones:
            try:
                zone = Zone.objects.get(cloud=self.cloud, zone_id=pr_zone.id)
            except Zone.DoesNotExist:
                log.info("Zone: %s/domain: %s not in the database, creating.",
                         pr_zone.id, pr_zone.domain)
                zone = Zone(cloud=self.cloud,
                            owner=self.cloud.owner,
                            zone_id=pr_zone.id)
                new_zones.append(zone)
            zone.deleted = None
            zone.domain = pr_zone.domain
            zone.type = pr_zone.type
            zone.ttl = pr_zone.ttl
            zone.extra = pr_zone.extra
            try:
                zone.save()
            except me.ValidationError as exc:
                log.error("Error updating %s: %s", zone, exc.to_dict())
                raise BadRequestError({
                    'msg': str(exc),
                    'errors': exc.to_dict()
                })
            except me.NotUniqueError as exc:
                log.error("Zone %s not unique error: %s", zone, exc)
                raise ZoneExistsError()
            zones.append(zone)
        self.cloud.owner.mapper.update(new_zones)

        # Delete any zones in the DB that were not returned by the provider
        # meaning they were deleted otherwise.
        Zone.objects(
            cloud=self.cloud, id__nin=[z.id for z in zones],
            deleted=None).update(set__deleted=datetime.datetime.utcnow())

        # Format zone information.
        return zones