def reset_all_zones(self): """ Reset all zones """ self._begin_op() db_session = self.db_session id_query = db_session.query(ZoneSM.id_, ZoneSM.name) id_query = ZoneSM.query_is_not_disabled_deleted(id_query) id_result = id_query.all() for zone_id, zone_name in id_result: try: zone_sm = db_session.query(ZoneSM)\ .filter(ZoneSM.id_ == zone_id).one() except NoResultFound: raise ZoneNotFoundByZoneId(zone_id) exec_zonesm(zone_sm, ZoneSMDoReset) self._finish_op()
def refresh_sg(self, sg_name): """ Refresh all zones on an SG """ self._begin_op() db_session = self.db_session sg = self._find_sg_byname(sg_name) id_query = db_session.query(ZoneSM.id_, ZoneSM.name)\ .filter(ZoneSM.sg_id == sg.id_) id_query = ZoneSM.query_is_configured(id_query) id_result = id_query.all() for zone_id, zone_name in id_result: try: zone_sm = db_session.query(ZoneSM)\ .filter(ZoneSM.id_ == zone_id).one() except NoResultFound: raise ZoneNotFoundByZoneId(zone_id) exec_zonesm(zone_sm, ZoneSMDoRefresh) self._finish_op()
def _queue_auto_ptr_data(self, auto_ptr_data): """ Queue auto PTR data as incremental updates against respective reverse zones. """ if not auto_ptr_data: return if not len(auto_ptr_data): return if not settings['auto_reverse']: return db_session = self.db_session # Create new update_group ug_dict = {} auto_ptr_privilege_flag = False for ptr_data in auto_ptr_data: # Ignore addresses we don't have reverse zone for query = db_session.query(ZoneSM)\ .join(ReverseNetwork)\ .filter(":address <<= reverse_networks.network")\ .params(address = ptr_data['address']) query = ZoneSM.query_is_not_deleted(query) query = ZoneSM.query_inc_updates(query) query = query.order_by(ReverseNetwork.network.desc())\ .limit(1) try: zone_sm = query.one() except NoResultFound: continue # Ignore invalid host names if not is_inet_hostname(ptr_data['hostname'], absolute=True, wildcard=False): log_error("Hostname '%s' is not a valid hostname." % ptr_data['hostname']) continue # Determine proposed update operation update_op = RROP_PTR_UPDATE_FORCE if ptr_data['force_reverse'] \ else RROP_PTR_UPDATE # Execute privilege checks ahead of time to save unnecessary churn # Better than needlessly going through whole rigamorole of # incremental update processing later on for no effect #1 See if old PTR exists to retrieve any RR reference # Both following also used lower down when generating RR_PTR label = label_from_address(ptr_data['address']) rr_ref = find_reference(db_session, ptr_data['reference'], raise_exc=False) # query for old record - this generates one select # Optimization - if check has previously suceeded, don't check # again as this is all checked further in if not auto_ptr_privilege_flag: qlabel= label[:label.rfind(zone_sm.name)-1] query = db_session.query(ResourceRecord)\ .filter(ResourceRecord.label == qlabel)\ .filter(ResourceRecord.zi_id == zone_sm.zi_candidate_id)\ .filter(ResourceRecord.disable == False)\ .filter(ResourceRecord.type_ == RRTYPE_PTR) old_rrs = query.all() old_rr = old_rrs[0] if len(old_rrs) else None # Check that we can proceed, only if check has not succeded yet if not check_auto_ptr_privilege(rr_ref, self.sectag, zone_sm, old_rr): if old_rr: log_debug("Zone '%s' - can't replace '%s' PTR" " as neither" " sectags '%s' vs '%s'" " references '%s' vs '%s'/'%s' (old PTR/rev zone)" "match ," " or values not given." % (zone_sm.name, old_rr.label, self.sectag.sectag, settings['admin_sectag'], rr_ref, old_rr.reference, zone_sm.reference)) else: log_debug("Zone '%s' - can't add '%s' PTR as neither" " sectags '%s' vs '%s'" " references '%s' vs '%s' (rev zone) match," " or values not given." % (zone_sm.name, qlabel, self.sectag.sectag, settings['admin_sectag'], rr_ref, zone_sm.reference)) continue auto_ptr_privilege_flag = True # Create a new update group if zone has not been seen before. try: update_group, zone_ttl = ug_dict.get(zone_sm) except (ValueError, TypeError): # Obtain reverse zone_ttl so PTR rrs can be created # Use candidate ZI as it always is available. # zi is published zi zi = self._get_zi(zone_sm.zi_candidate_id) if not zi: log_error("Zone '%s': does not have candidate zi." % zone_sm.name) continue zone_ttl = zi.zone_ttl update_group = new_update_group(db_session, None, zone_sm, None, ptr_only=True, sectag=self.sectag.sectag) ug_dict[zone_sm] = (update_group, zone_ttl) # Allocate RR_PTR update record rr = RR_PTR(label=label, zone_ttl=zone_ttl, rdata=ptr_data['hostname'], disable=ptr_data['disable'], domain=zone_sm.name, update_op=update_op) rr.ref_id = rr_ref.id_ if rr_ref else None rr.reference = rr_ref # Chain on RR_PTR update record update_group.update_ops.append(rr) # Flush everything to disk db_session.flush() # Issue zone refreshes to implement PTR changes for zone_sm in ug_dict: if zone_sm.is_disabled(): continue exec_zonesm(zone_sm, ZoneSMDoRefresh) # Make sure everything is committed db_session.commit()
def restore_named_db(self): """ Dump dms DB to Named zone files and include file For quick DR secnario """ self._begin_op() # Exception processing make the both of the following a bit of a # rats nest # Check that named is not running cmdline = [settings['rndc_path'], 'status'] try: check_output(cmdline, stderr=STDOUT) except CalledProcessError as exc: if exc.returncode != 1: raise exc pass else: raise NamedStillRunning(0) # Check that dmsdmd is not running try: pid_file = open(settings['pid_file'],'r') dmsdmd_pid = int(pid_file.readline().strip()) pid_file.close() # The following throws exceptions if process does not exist etc! # Sending signal 0 does not touch process, but call succeeds # if it exists os.kill(dmsdmd_pid, 0) except ValueError as exc: # Error from int() type conversion above raise PidFileValueError(pid_file, exc) except (IOError,OSError) as exc: if (exc.errno in (errno.ESRCH,)): # This is from kill() raise DmsdmdStillRunning(dmsdmd_pid) # File IO causes this elif (exc.errno in (errno.ENOENT,)): # This file may be removed by dameon nicely shutting down. pass else: # No exceptions, dmsdmd is running!!! raise DmsdmdStillRunning(dmsdmd_pid) # Dump out each zone file db_session = self.db_session id_query = db_session.query(ZoneSM.id_, ZoneSM.name) id_query = ZoneSM.query_is_not_disabled_deleted(id_query) id_result = id_query.all() for zone_id, zone_name in id_result: try: zone_sm = db_session.query(ZoneSM)\ .filter(ZoneSM.id_ == zone_id).one() except NoResultFound: raise ZoneNotFoundByZoneId(zone_id) try: zone_sm.write_zone_file(db_session, ZoneFileWriteInternalError) zone_sm.state = ZSTATE_PUBLISHED db_session.commit() except ZoneFileWriteInternalError as exc: db_session.rollback() raise ZoneFileWriteError(str(exc)) # Write out config file include master_sm = get_master_sm(db_session) try: master_sm.write_named_conf_includes(db_session, NamedConfWriteInternalError) except NamedConfWriteInternalError as exc: raise NamedConfWriteError(str(exc)) self._finish_op()
def _queue_auto_ptr_data(self, auto_ptr_data): """ Queue auto PTR data as incremental updates against respective reverse zones. """ if not auto_ptr_data: return if not len(auto_ptr_data): return if not settings['auto_reverse']: return db_session = self.db_session # Create new update_group ug_dict = {} auto_ptr_privilege_flag = False for ptr_data in auto_ptr_data: # Ignore addresses we don't have reverse zone for query = db_session.query(ZoneSM)\ .join(ReverseNetwork)\ .filter(text(":address <<= reverse_networks.network"))\ .params(address = ptr_data['address']) query = ZoneSM.query_is_not_deleted(query) query = ZoneSM.query_inc_updates(query) query = query.order_by(ReverseNetwork.network.desc())\ .limit(1) try: zone_sm = query.one() except NoResultFound: continue # Ignore invalid host names if not is_inet_hostname( ptr_data['hostname'], absolute=True, wildcard=False): log_error("Hostname '%s' is not a valid hostname." % ptr_data['hostname']) continue # Determine proposed update operation update_op = RROP_PTR_UPDATE_FORCE if ptr_data['force_reverse'] \ else RROP_PTR_UPDATE # Execute privilege checks ahead of time to save unnecessary churn # Better than needlessly going through whole rigamorole of # incremental update processing later on for no effect #1 See if old PTR exists to retrieve any RR reference # Both following also used lower down when generating RR_PTR label = label_from_address(ptr_data['address']) rr_ref = find_reference(db_session, ptr_data['reference'], raise_exc=False) # query for old record - this generates one select # Optimization - if check has previously suceeded, don't check # again as this is all checked further in if not auto_ptr_privilege_flag: qlabel = label[:label.rfind(zone_sm.name) - 1] query = db_session.query(ResourceRecord)\ .filter(ResourceRecord.label == qlabel)\ .filter(ResourceRecord.zi_id == zone_sm.zi_candidate_id)\ .filter(ResourceRecord.disable == False)\ .filter(ResourceRecord.type_ == RRTYPE_PTR) old_rrs = query.all() old_rr = old_rrs[0] if len(old_rrs) else None # Check that we can proceed, only if check has not succeded yet if not check_auto_ptr_privilege(rr_ref, self.sectag, zone_sm, old_rr): if old_rr: log_debug( "Zone '%s' - can't replace '%s' PTR" " as neither" " sectags '%s' vs '%s'" " references '%s' vs '%s'/'%s' (old PTR/rev zone)" "match ," " or values not given." % (zone_sm.name, old_rr.label, self.sectag.sectag, settings['admin_sectag'], rr_ref, old_rr.reference, zone_sm.reference)) else: log_debug("Zone '%s' - can't add '%s' PTR as neither" " sectags '%s' vs '%s'" " references '%s' vs '%s' (rev zone) match," " or values not given." % (zone_sm.name, qlabel, self.sectag.sectag, settings['admin_sectag'], rr_ref, zone_sm.reference)) continue auto_ptr_privilege_flag = True # Create a new update group if zone has not been seen before. try: update_group, zone_ttl = ug_dict.get(zone_sm) except (ValueError, TypeError): # Obtain reverse zone_ttl so PTR rrs can be created # Use candidate ZI as it always is available. # zi is published zi zi = self._get_zi(zone_sm.zi_candidate_id) if not zi: log_error("Zone '%s': does not have candidate zi." % zone_sm.name) continue zone_ttl = zi.zone_ttl update_group = new_update_group(db_session, None, zone_sm, None, ptr_only=True, sectag=self.sectag.sectag) ug_dict[zone_sm] = (update_group, zone_ttl) # Allocate RR_PTR update record rr = RR_PTR(label=label, zone_ttl=zone_ttl, rdata=ptr_data['hostname'], disable=ptr_data['disable'], domain=zone_sm.name, update_op=update_op) rr.ref_id = rr_ref.id_ if rr_ref else None rr.reference = rr_ref # Chain on RR_PTR update record update_group.update_ops.append(rr) # Flush everything to disk db_session.flush() # Issue zone refreshes to implement PTR changes for zone_sm in ug_dict: if zone_sm.is_disabled(): continue exec_zonesm(zone_sm, ZoneSMDoRefresh) # Make sure everything is committed db_session.commit()