def build_debug_soa(request, soa_pk): soa = get_object_or_404(SOA, pk=soa_pk) # DEBUG_BUILD_STRING = build_zone(soa, root_domain) # Figure out what sort of domains are in this zone. try: private_view = View.objects.get(name='private') public_view = View.objects.get(name='public') private_data = build_zone_data(private_view, soa.root_domain, soa) private_data = private_data.format(serial=soa.serial) public_data = build_zone_data(public_view, soa.root_domain, soa) public_data = public_data.format(serial=soa.serial) output = _(""" ;======= Private Data ======= {0} ;======= Public Data ======= {1} """.format(private_data, public_data)) except Exception: return HttpResponse( json.dumps({"error": "HOLY SHIT SOMETHING WENT WRONG!!!"})) return render(request, 'mozbind/sample_build.html', { 'data': output, 'soa': soa })
def build_debug_soa(request, soa_pk): soa = get_object_or_404(SOA, pk=soa_pk) # DEBUG_BUILD_STRING = build_zone(soa, root_domain) # Figure out what sort of domains are in this zone. try: private_view = View.objects.get(name='private') public_view = View.objects.get(name='public') private_data = build_zone_data(private_view, soa.root_domain, soa) private_data = private_data.format(serial=soa.serial) public_data = build_zone_data(public_view, soa.root_domain, soa) public_data = public_data.format(serial=soa.serial) output = _( """ ;======= Private Data ======= {0} ;======= Public Data ======= {1} """.format(private_data, public_data)) except Exception: return HttpResponse(json.dumps( {"error": "HOLY SHIT SOMETHING WENT WRONG!!!"})) return render(request, 'mozbind/sample_build.html', {'data': output, 'soa': soa})
def build_views(self, soa, root_domain, gen_config, force_rebuild): """ For a given soa build a zone file for every view in the database. This function returns a list contaning tuples, where each tuple contains: * An ORM view object * A dictionary containing file information about where a zone should exist on the filesystem * A zone file with eveything but the SOA's serial filled out. This function also introspects a zone's existing bind file (if it exists) to ensure no manual changes to the serial have been made. """ view_bundles = [] self.log("SOA was seen with dirty == {0}".format(force_rebuild), root_domain=root_domain) # This for loop decides which views will be canidates for # rebuilding. for view in View.objects.all(): self.log("++++++ Looking at < {0} > view ++++++".format(view.name), root_domain=root_domain) t_start = time.time() # tic view_data = build_zone_data(view, root_domain, soa, logf=self.log) build_time = time.time() - t_start # toc self.log("< {0} > Built {1} data in {2} seconds".format( view.name, soa, build_time), root_domain=root_domain, build_time=build_time) if not view_data: if gen_config: self.log( "< {0} > No data found in this view. No zone file " "will be made or included in any config for this " "view.".format(view.name), root_domain=root_domain) continue if gen_config: self.log( "< {0} > Non-empty data set for this view. Its zone file " "will be included in the config.".format(view.name), root_domain=root_domain) file_meta = self.get_file_meta(view, root_domain, soa) # Detect when someone fiddles with the serial manulally. # safe_serial will be a serial that is ahead of the current serial # and should be used as the SOA's new serial was_bad_prev, safe_serial = self.verify_previous_build( file_meta, view, root_domain, soa) if was_bad_prev: soa.serial = safe_serial view_bundles.append((view, file_meta, view_data)) view_str = ' | '.join([v.name for v, _, _ in view_bundles]) self.log("----- Building < {0} > ------".format(view_str), root_domain=root_domain) return view_bundles
def build_zone_files(self, soa_pks_to_rebuild): zone_stmts = {} for soa in SOA.objects.all(): # If anything happens during this soa's build we need to mark # it as dirty so it can be rebuild try: root_domain = soa.root_domain # This is an expensive lookup if not root_domain: # TODO, figure out how to send a nagios alert on this case. self.log("No root domain found in zone {0}".format(soa)) fail_mail( "{0} is an orphan. It's being skipped in " "the builds".format(soa), subject="{0} is " "orphaned".format(soa)) continue """ General order of things: * Find which views should have a zone file built and add them to a list. * If any of the view's zone file have been tampered with or the zone is new, trigger the rebuilding of all the zone's view files. (rebuil all views in a zone keeps the serial synced across all views) * Either rebuild all of a zone's view files because one view needed to be rebuilt due to tampering or the zone was dirty (again, this is to keep their serial synced) or just call named-checkzone on the existing zone files for good measure. Also generate a zone statement and add it to a dictionary for later use during BIND configuration generation. """ force_rebuild = soa.pk in soa_pks_to_rebuild or soa.dirty if force_rebuild: soa.dirty = False soa.save() self.log('====== Processing {0} {1} ======'.format( root_domain, soa.serial) ) views_to_build = [] self.log( "SOA was seen with dirty == {0}".format(force_rebuild), root_domain=root_domain ) # This for loop decides which views will be canidates for # rebuilding. for view in View.objects.all(): self.log("++++++ Looking at < {0} > view ++++++". format(view.name), root_domain=root_domain) t_start = time.time() # tic view_data = build_zone_data(view, root_domain, soa, logf=self.log) build_time = time.time() - t_start # toc self.log('< {0} > Built {1} data in {2} seconds' .format(view.name, soa, build_time), root_domain=root_domain, build_time=build_time) if not view_data: self.log('< {0} > No data found in this view. ' 'No zone file will be made or included in any' ' config for this view.'.format(view.name), root_domain=root_domain) continue self.log('< {0} > Non-empty data set for this ' 'view. Its zone file will be included in the ' 'config.'.format(view.name), root_domain=root_domain) file_meta = self.get_file_meta(view, root_domain, soa) was_bad_prev, safe_serial = self.verify_previous_build( file_meta, view, root_domain, soa ) if was_bad_prev: soa.serial = safe_serial force_rebuild = True views_to_build.append( (view, file_meta, view_data) ) self.log( '----- Building < {0} > ------'.format( ' | '.join([v.name for v, _, _ in views_to_build]) ), root_domain=root_domain ) next_serial = soa.get_incremented_serial() if force_rebuild: # Bypass save so we don't have to save a possible stale # 'dirty' value to the db. SOA.objects.filter(pk=soa.pk).update(serial=next_serial) self.log('Zone will be rebuilt at serial {0}' .format(next_serial), root_domain=root_domain) else: self.log('Zone is stable at serial {0}' .format(soa.serial), root_domain=root_domain) for view, file_meta, view_data in views_to_build: if (root_domain.name, view.name) in ZONES_WITH_NO_CONFIG: self.log( '!!! Not going to emit zone statements for ' '{0}\n'.format(root_domain.name), root_domain=root_domain ) else: view_zone_stmts = zone_stmts.setdefault(view.name, []) # If we see a view in this loop it's going to end up in # the config view_zone_stmts.append( self.render_zone_stmt(soa, root_domain, file_meta) ) # If it's dirty or we are rebuilding another view, rebuild # the zone if force_rebuild: self.log( 'Rebuilding < {0} > view file {1}' .format(view.name, file_meta['prod_fname']), root_domain=root_domain) prod_fname = self.build_zone( view, file_meta, # Lazy string evaluation view_data.format(serial=next_serial), root_domain ) assert prod_fname == file_meta['prod_fname'] else: self.log( 'NO REBUILD needed for < {0} > view file {1}' .format(view.name, file_meta['prod_fname']), root_domain=root_domain ) # run named-checkzone for good measure if self.STAGE_ONLY: self.log("Not calling named-checkconf.", root_domain=root_domain) else: self.named_checkzone( file_meta['prod_fname'], root_domain ) except Exception: soa.schedule_rebuild() raise return zone_stmts
def build_views(self, soa, root_domain, gen_config, force_rebuild): """ For a given soa build a zone file for every view in the database. This function returns a list contaning tuples, where each tuple contains: * An ORM view object * A dictionary containing file information about where a zone should exist on the filesystem * A zone file with eveything but the SOA's serial filled out. This function also introspects a zone's existing bind file (if it exists) to ensure no manual changes to the serial have been made. """ view_bundles = [] self.log( "SOA was seen with dirty == {0}".format(force_rebuild), root_domain=root_domain ) # This for loop decides which views will be canidates for # rebuilding. for view in View.objects.all(): self.log( "++++++ Looking at < {0} > view ++++++". format(view.name), root_domain=root_domain ) t_start = time.time() # tic view_data = build_zone_data( view, root_domain, soa, logf=self.log ) build_time = time.time() - t_start # toc self.log( "< {0} > Built {1} data in {2} seconds".format( view.name, soa, build_time), root_domain=root_domain, build_time=build_time ) if not view_data: if gen_config: self.log( "< {0} > No data found in this view. No zone file " "will be made or included in any config for this " "view.".format(view.name), root_domain=root_domain ) continue if gen_config: self.log( "< {0} > Non-empty data set for this view. Its zone file " "will be included in the config.".format(view.name), root_domain=root_domain ) file_meta = self.get_file_meta(view, root_domain, soa) # Detect when someone fiddles with the serial manulally. # safe_serial will be a serial that is ahead of the current serial # and should be used as the SOA's new serial was_bad_prev, safe_serial = self.verify_previous_build( file_meta, view, root_domain, soa ) if was_bad_prev: soa.serial = safe_serial view_bundles.append( (view, file_meta, view_data) ) view_str = ' | '.join([v.name for v, _, _ in view_bundles]) self.log( "----- Building < {0} > ------".format(view_str), root_domain=root_domain ) return view_bundles