def create_subzone(new_zone, parent_zone, from_profile, soa_attributes, user, inherit_rights=True, inherit_zone_groups=True): ''' Create views and move rrs from parent zone. Records from the parent zones have priority over the ones from the profile. Copy @ NS records from subzone to parent zone. If inherit_rights is True, inherit user rights from parent zone. If inherit_zone_groups is True, inherit zone-group membership from parent zone. No zone-group rights are checked. This is necessary so net_admins can create subnets without access to the zone-group where the parent reverse zone is a member. If inherit_owner is True, inherit the owner from parent zone. ''' # map parent view id to child view view_id_map = {} parent_views_ids = [view.id for view in parent_zone.views] for view in parent_zone.views: view_id_map[view.id] = ZoneView.create(new_zone, view.name, from_profile=from_profile, soa_attributes=soa_attributes, copy_rrs=False) Messages.info('Creating views %s for zone %s' % (', '.join([view.name for view in new_zone.views]), new_zone.name)) for rr in RR.query.filter(RR.zoneview_id.in_(parent_views_ids))\ .filter(or_(RR.name.endswith('.' + new_zone.name + '.'), RR.name == new_zone.name + '.')): view_msg = (' view ' + rr.view.name) if len(parent_zone.views) > 1 else '' msg_info = (rr.bind_str(relative=True), new_zone.name + view_msg, parent_zone.name + view_msg) rr.notify_delete() rr.view = view_id_map[rr.zoneview_id] rr.value = RR.get_class(rr.type).fqdn_target(rr.value, parent_zone.name) try: check_new_rr(rr) Messages.info('Moving RR %s in zone %s from zone %s' % msg_info) rr.notify_insert() except InvalidParameterError: db.session.delete(rr) Messages.warn('Rejected to move RR %s in zone %s, deleted RR from zone %s' % msg_info) if from_profile is not None: for view in new_zone.views: apply_profile(view, new_zone, from_profile) for parent_view in parent_zone.views: if inherit_zone_groups: for group in parent_view.groups: zone_group_add_zone(group, new_zone, view_id_map[parent_view.id]) if inherit_rights: rights = AccessRight.query.filter_by(object_class='ZoneView', object_id=parent_view.id).all() for right in rights: for group in right.groups: group.rights.add(AccessRight.find_or_create(access=right.access, object_id=view_id_map[parent_view.id].id, object_class=right.object_class))
def f(self, key, value): try: value = int(value) except: value = value.upper() if type(value) == int: if reserved and value in reserved: raise InvalidParameterError("Invalid %s: %s" % (key, value)) if value not in enum.values(): Messages.warn('%s value %s is unassigned' % (key, value)) return validate_uint8(self, key, value) else: if value in enum: return enum[value] else: raise InvalidParameterError("Invalid %s: %s" % (key, value))
def delete_with_references(query, free_ips, references, user): if references not in ('warn', 'error', 'delete', 'ignore'): raise InvalidParameterError( 'Invalid value for references (must be warn, error, delete or ignore)' ) rrs = query.all() if free_ips: ipblocks = set() to_delete = set() done = False while rrs and not done: to_delete |= set(rrs) orphaned = set() # RRs orphaned by deleting rrs forward_reverse = set() # forward or reverse RRs corresponding to rrs for rr in rrs: for orr in orphaned_references(rr, to_delete).all(): if (rr.type == 'PTR' and orr.type in ('A', 'AAAA')) or \ (rr.type in ('A', 'AAAA') and orr.type == 'PTR'): if references != 'ignore': forward_reverse.add(orr) elif orr not in rrs: orphaned.add(orr) if references in ('warn', 'error', 'ignore'): for rr in orphaned: logging.debug('%s referenced by:\n%s' % (rr.target, rr)) for rr_target in set(rr.target for rr in orphaned): if references == 'warn': Messages.warn('%s is referenced by other records' % rr_target) elif references == 'error': raise DimError('%s is referenced by other records' % rr_target) done = True rrs = (orphaned | forward_reverse) - to_delete to_delete |= forward_reverse for rr in sorted(to_delete, key=lambda rr: (rr.type, rr.name, rr.target, rr.value, rr.id)): Messages.info("Deleting RR %s from %s" % (rr.bind_str(relative=True), rr.view)) if free_ips and rr.ipblock_id: ipblocks.add(rr.ipblock_id) delete_single_rr(rr, user) if free_ips and ipblocks: free_ipblocks(ipblocks)
def validate_strings(self, key, value): if isinstance(value, basestring): strings = _parse_strings(value) elif isinstance(value, list): strings = map(lambda v: _unescapify(v), value) else: raise ValueError('%s must be either a string or a list of strings' % key) # Split strings longer than 255 split_strings = [] splits = 0 for s in strings: while len(s) > 255: splits += 1 split_strings.append(s[:255]) s = s[255:] if s: split_strings.append(s) if splits: Messages.warn( 'A TXT record string was longer than 255 characters, it was automatically divided.' ) return ' '.join('"' + dns.rdata._escapify(s) + '"' for s in split_strings)
def create_single_rr(name, rr_type, zone, view, user, overwrite=False, **kwargs): ''' :type zone: Zone :type view: string :param view: name of the view :param rr_type: RR type (string) :return: True if the record was created or already existed ''' view = get_view(zone, view) existed = False created = True name = make_fqdn(name, view.zone.name) rr_query = RR.query.filter(RR.name == name).filter(RR.type == rr_type)\ .join(ZoneView).filter(RR.view == view) new_rr = RR.create(name=name, type=rr_type, view=view, **kwargs) rrs = rr_query.all() if rrs: if overwrite: for rr in rrs: Messages.warn("Deleting RR %s from %s" % (rr.bind_str(relative=True), rr.view)) delete_single_rr(rr, user) else: samerr = None for rr in rrs: if rr.value == new_rr.value and (rr.type not in ( 'A', 'AAAA', 'PTR') or rr.ipblock == new_rr.ipblock): samerr = rr break if samerr: created = False existed = True Messages.info("%s already exists" % samerr) else: if rr_type == 'PTR': # Don't allow PTR round robin records created = False Messages.warn("Not overwriting: %s" % rrs[0]) else: Messages.warn( "The name %s already existed, creating round robin record" % name) if created: if rr_type == 'RP': point_to = _same_view_or_different_zone(new_rr).filter( RR.name == new_rr.target) if point_to.filter(RR.type == 'TXT').count() == 0: Messages.warn('TXT Record %s not found' % (new_rr.target, )) elif rr_type == 'SSHFP': same_name = _same_view_or_different_zone(new_rr).filter( RR.name == new_rr.name) if same_name.filter(or_(RR.type == 'A', RR.type == 'AAAA')).count() == 0: Messages.warn('No A or AAAA found for %s' % (new_rr.name, )) check_new_rr(new_rr) Messages.info("Creating RR {rr}{comment_msg} in {view_msg}".format( rr=new_rr.bind_str(relative=True), comment_msg=' comment {0}'.format(kwargs['comment']) if kwargs.get( 'comment', None) else '', view_msg=new_rr.view)) if new_rr.target and rr_type not in ['PTR', 'RP']: # Creating a PTR record also creates the A/AAAA record if _same_view_or_different_zone(new_rr).filter( RR.name == new_rr.target).count() == 0: Messages.warn('%s does not exist.' % new_rr.target) new_rr.insert() return created or existed