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
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
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)
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)
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
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()
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"
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