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
    })
Exemplo n.º 2
0
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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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