1############################################################################ 2# Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3# 4# SPDX-License-Identifier: MPL-2.0 5# 6# This Source Code Form is subject to the terms of the Mozilla Public 7# License, v. 2.0. If a copy of the MPL was not distributed with this 8# file, you can obtain one at https://mozilla.org/MPL/2.0/. 9# 10# See the COPYRIGHT file distributed with this work for additional 11# information regarding copyright ownership. 12############################################################################ 13 14from pathlib import Path 15import re 16import sys 17 18from typing import List, Tuple 19 20from docutils import nodes 21from docutils.nodes import Node, system_message 22from docutils.parsers.rst import roles 23 24from sphinx import addnodes 25 26try: 27 from sphinx.util.docutils import ReferenceRole 28except ImportError: 29 # pylint: disable=too-few-public-methods 30 class ReferenceRole(roles.GenericRole): 31 """ 32 The ReferenceRole class (used as a base class by GitLabRefRole 33 below) is only defined in Sphinx >= 2.0.0. For older Sphinx 34 versions, this stub version of the ReferenceRole class is used 35 instead. 36 """ 37 38 def __init__(self): 39 super().__init__("", nodes.strong) 40 41 42GITLAB_BASE_URL = "https://gitlab.isc.org/isc-projects/bind9/-/" 43KNOWLEDGEBASE_BASE_URL = "https://kb.isc.org/docs/" 44 45 46# Custom Sphinx role enabling automatic hyperlinking to security advisory in 47# ISC Knowledgebase 48class CVERefRole(ReferenceRole): 49 def __init__(self, base_url: str) -> None: 50 self.base_url = base_url 51 super().__init__() 52 53 def run(self) -> Tuple[List[Node], List[system_message]]: 54 cve_identifier = "(CVE-%s)" % self.target 55 56 target_id = "index-%s" % self.env.new_serialno("index") 57 entries = [ 58 ("single", "ISC Knowledgebase; " + cve_identifier, target_id, "", None) 59 ] 60 61 index = addnodes.index(entries=entries) 62 target = nodes.target("", "", ids=[target_id]) 63 self.inliner.document.note_explicit_target(target) 64 65 try: 66 refuri = self.base_url + "cve-%s" % self.target 67 reference = nodes.reference( 68 "", "", internal=False, refuri=refuri, classes=["cve"] 69 ) 70 if self.has_explicit_title: 71 reference += nodes.strong(self.title, self.title) 72 else: 73 reference += nodes.strong(cve_identifier, cve_identifier) 74 except ValueError: 75 error_text = "invalid ISC Knowledgebase identifier %s" % self.target 76 msg = self.inliner.reporter.error(error_text, line=self.lineno) 77 prb = self.inliner.problematic(self.rawtext, self.rawtext, msg) 78 return [prb], [msg] 79 80 return [index, target, reference], [] 81 82 83# Custom Sphinx role enabling automatic hyperlinking to GitLab issues/MRs. 84class GitLabRefRole(ReferenceRole): 85 def __init__(self, base_url: str) -> None: 86 self.base_url = base_url 87 super().__init__() 88 89 def run(self) -> Tuple[List[Node], List[system_message]]: 90 gl_identifier = "[GL %s]" % self.target 91 92 target_id = "index-%s" % self.env.new_serialno("index") 93 entries = [("single", "GitLab; " + gl_identifier, target_id, "", None)] 94 95 index = addnodes.index(entries=entries) 96 target = nodes.target("", "", ids=[target_id]) 97 self.inliner.document.note_explicit_target(target) 98 99 try: 100 refuri = self.build_uri() 101 reference = nodes.reference( 102 "", "", internal=False, refuri=refuri, classes=["gl"] 103 ) 104 if self.has_explicit_title: 105 reference += nodes.strong(self.title, self.title) 106 else: 107 reference += nodes.strong(gl_identifier, gl_identifier) 108 except ValueError: 109 error_text = "invalid GitLab identifier %s" % self.target 110 msg = self.inliner.reporter.error(error_text, line=self.lineno) 111 prb = self.inliner.problematic(self.rawtext, self.rawtext, msg) 112 return [prb], [msg] 113 114 return [index, target, reference], [] 115 116 def build_uri(self): 117 if self.target[0] == "#": 118 return self.base_url + "issues/%d" % int(self.target[1:]) 119 if self.target[0] == "!": 120 return self.base_url + "merge_requests/%d" % int(self.target[1:]) 121 raise ValueError 122 123 124def setup(app): 125 roles.register_local_role("cve", CVERefRole(KNOWLEDGEBASE_BASE_URL)) 126 roles.register_local_role("gl", GitLabRefRole(GITLAB_BASE_URL)) 127 app.add_crossref_type("iscman", "iscman", "pair: %s; manual page") 128 129 130# 131# Configuration file for the Sphinx documentation builder. 132# 133# This file only contains a selection of the most common options. For a full 134# list see the documentation: 135# http://www.sphinx-doc.org/en/master/config 136 137# -- Path setup -------------------------------------------------------------- 138 139# If extensions (or modules to document with autodoc) are in another directory, 140# add these directories to sys.path here. If the directory is relative to the 141# documentation root, make it absolute. 142# 143sys.path.append(str(Path(__file__).resolve().parent / "_ext")) 144sys.path.append(str(Path(__file__).resolve().parent.parent / "misc")) 145 146# -- Project information ----------------------------------------------------- 147 148project = "BIND 9" 149# pylint: disable=redefined-builtin 150copyright = "2023, Internet Systems Consortium" 151author = "Internet Systems Consortium" 152 153m4_vars = {} 154with open("../../configure.ac", encoding="utf-8") as configure_ac: 155 for line in configure_ac: 156 match = re.match( 157 r"m4_define\(\[(?P<key>bind_VERSION_[A-Z]+)\], (?P<val>[^)]*)\)dnl", line 158 ) 159 if match: 160 m4_vars[match.group("key")] = match.group("val") 161 162version = "%s.%s.%s%s" % ( 163 m4_vars["bind_VERSION_MAJOR"], 164 m4_vars["bind_VERSION_MINOR"], 165 m4_vars["bind_VERSION_PATCH"], 166 m4_vars["bind_VERSION_EXTRA"], 167) 168release = version 169 170# -- General configuration --------------------------------------------------- 171 172# Add any Sphinx extension module names here, as strings. They can be 173# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 174# ones. 175extensions = ["namedconf", "rndcconf"] 176 177# Add any paths that contain templates here, relative to this directory. 178templates_path = ["_templates"] 179 180# List of patterns, relative to source directory, that match files and 181# directories to ignore when looking for source files. 182# This pattern also affects html_static_path and html_extra_path. 183exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "*.inc.rst"] 184 185# The master toctree document. 186master_doc = "index" 187 188# -- Options for HTML output ------------------------------------------------- 189 190# The theme to use for HTML and HTML Help pages. See the documentation for 191# a list of builtin themes. 192# 193html_theme = "sphinx_rtd_theme" 194html_static_path = ["_static"] 195html_css_files = ["custom.css"] 196 197# -- Options for EPUB output ------------------------------------------------- 198 199epub_basename = "Bv9ARM" 200 201# -- Options for LaTeX output ------------------------------------------------ 202latex_engine = "xelatex" 203 204# pylint disable=line-too-long 205latex_documents = [ 206 ( 207 master_doc, 208 "Bv9ARM.tex", 209 "BIND 9 Administrator Reference Manual", 210 author, 211 "manual", 212 ), 213] 214 215latex_logo = "isc-logo.pdf" 216 217# 218# The rst_epilog will be completely overwritten from the Makefile, 219# the definition here is provided purely for situations when 220# sphinx-build is run by hand. 221# 222rst_epilog = """ 223.. |rndc_conf| replace:: ``/etc/rndc.conf`` 224.. |rndc_key| replace:: ``/etc/rndc.key`` 225.. |named_conf| replace:: ``/etc/named.conf`` 226.. |bind_keys| replace:: ``/etc/bind.keys`` 227.. |named_pid| replace:: ``/run/named.pid`` 228.. |session_key| replace:: ``/run/session.key`` 229""" 230