diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 0000000..cf9407b --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,55 @@ +name: Build GitHub Pages +on: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: + id-token: write + contents: write + pages: write + +jobs: + build_mkdocs: + runs-on: ubuntu-latest + steps: + - name: Checkout + # This action checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it. + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + with: + fetch-depth: 0 + - name: Install Python + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + with: + python-version: '3.12' + - run: pip install \ + 'mkdocs-material>=9.5.0,<9.6.0' + - run: mkdocs gh-deploy --config-file mkdocs.yml --force + + deploy_mkdocs: + needs: build_mkdocs + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + # This action checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it. + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + with: + ref: gh-pages + - name: Setup Pages + # A GitHub Action to enable Pages and extract various metadata about a site. + uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0 + - name: Upload artifact + # A composite Action for packaging and uploading artifact that can be deployed to GitHub Pages. + uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1 + with: + path: '.' + - name: Deploy to GitHub Pages + # This action is used to deploy Actions artifacts to GitHub Pages. + id: deployment + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 diff --git a/docs/assets/diagrams-high-level-simple.png b/docs/assets/diagrams-high-level-simple.png new file mode 100644 index 0000000..3b84917 Binary files /dev/null and b/docs/assets/diagrams-high-level-simple.png differ diff --git a/docs/assets/favicon.png b/docs/assets/favicon.png new file mode 100644 index 0000000..c8d088f Binary files /dev/null and b/docs/assets/favicon.png differ diff --git a/docs/assets/logo.webp b/docs/assets/logo.webp new file mode 100644 index 0000000..2451331 Binary files /dev/null and b/docs/assets/logo.webp differ diff --git a/docs/guides/rrsets.md b/docs/guides/rrsets.md new file mode 100644 index 0000000..57c2743 --- /dev/null +++ b/docs/guides/rrsets.md @@ -0,0 +1,40 @@ +# RRset deployment + +## Specification + +The specification of the `RRset` contains the following fields: + +| Field | Type | Required | Description | +| ----- | ---- |:--------:| ----------- | +| type | string | Y | Type of the record (e.g. "A", "PTR", "MX") | +| ttl | uint32 | Y | DNS TTL of the records, in seconds +| records | []string | Y | All records in this Resource Record Set +| comment | string | N | Comment on RRSet | +| zoneRef | ZoneRef | Y | ZoneRef reference the zone the RRSet depends on | + +The specification of the `ZoneRef` contains the following fields: + +| Field | Type | Required | Description | +| ----- | ---- |:--------:| ----------- | +| name | string | Y | Name of the zone | + +## Example + +```yaml +apiVersion: dns.cav.enablers.ob/v1alpha1 +kind: RRset +metadata: + labels: + app.kubernetes.io/name: powerdns-operator + app.kubernetes.io/managed-by: kustomize + name: test.helloworld.com +spec: + comment: nothing to tell + type: A + ttl: 300 + records: + - 1.1.1.1 + - 2.2.2.2 + zoneRef: + name: helloworld.com +``` \ No newline at end of file diff --git a/docs/guides/zones.md b/docs/guides/zones.md new file mode 100644 index 0000000..de99b82 --- /dev/null +++ b/docs/guides/zones.md @@ -0,0 +1,29 @@ +# Zone deployment + +## Specification + +The specification of the `Zone` contains the following fields: + +| Field | Type | Required | Description | +| ----- | ---- |:--------:| ----------- | +| kind | string | Y | Kind of the zone, one of "Native", "Master", "Slave", "Producer", "Consumer" | +| nameservers | []string | Y | List of the nameservers of the zone | +| catalog | string | N | The catalog this zone is a member of | + +## Example + +```yaml +apiVersion: dns.cav.enablers.ob/v1alpha1 +kind: Zone +metadata: + labels: + app.kubernetes.io/name: powerdns-operator + app.kubernetes.io/managed-by: kustomize + name: helloworld.com +spec: + nameservers: + - ns1.helloworld.com + - ns2.helloworld.com + kind: Master + catalog: catalog.helloworld +``` diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..2de2b33 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,23 @@ +--- +hide: + - toc +--- + +# Introduction + +![high-level](./assets/diagrams-high-level-simple.png) + +**PowerDNS Operator** is a Kubernetes operator that manages PowerDNS service. + +With PowerDNS Operator you can manage zones, records and other PowerDNS resources directly from Kubernetes. It is designed to be a simple and easy-to-use solution to manage PowerDNS directly from Kubernetes through Custom Resources. The PowerDNS service can be located inside or outside of Kubernetes, it does not matter since the Operator relies on the PowerDNS API. + +!!! info + This project use the official [PowerDNS API](https://doc.powerdns.com/authoritative/http-api/) and cannot be plugged to [PowerDNS-Admin](https://github.com/PowerDNS-Admin/PowerDNS-Admin) project which implement its own specific API on top PowerDNS's API. There is no issue if you want to use both projects together, but the operator can only relies on the official API and you may notice issues if you try to use PowerDNS-Admin to manage the same resources as the operator. + +### Why use PowerDNS Operator? + +We needed to offer DNS capabilities to users and considered relying on the PowerDNS-Admin project. However, we wanted a more flexible solution that could be natively integrated with our existing Kubernetes infrastructure. We were also looking for a solution that could be easily integrated with our GitOps workflow to automate the creation of DNS records as well as other resources such as Ingress, Services, etc. + +Another reason is that the PowerDNS-Admin project is not in [good health](https://github.com/PowerDNS-Admin/PowerDNS-Admin/discussions/1708) and will probably be rewritten in the future. We wanted a solution that is more reliable and easily maintained. + +The PowerDNS Operator is a convenient way to offer self-service DNS capabilities to users, allowing them to create resources directly in the Kubernetes cluster. Additionally, you can use Backstage or any Internal Developer Platform and connect it to the Kubernetes API server that contains the PowerDNS Operator if you don't want to grant direct access to the Kubernetes cluster. diff --git a/docs/introduction/faq.md b/docs/introduction/faq.md new file mode 100644 index 0000000..7703552 --- /dev/null +++ b/docs/introduction/faq.md @@ -0,0 +1,17 @@ +# FAQ + +## Can I use PowerDNS-Admin and PowerDNS Operator together? + +No, the operator only supports the official PowerDNS API. The PowerDNS-Admin project implements its own specific API on top of PowerDNS's API. There is no issue if you want to use both projects together, but the operator can only rely on the official API. You may notice issues if you try to use PowerDNS-Admin to manage the same resources as the operator. + +## Can I manage multiple PowerDNS servers with a single operator? + +No, the operator is designed to manage a single PowerDNS server. If you need to manage multiple PowerDNS servers, you will have to deploy multiple instances of the operator in multiple Kubernetes clusters, each one managing a different PowerDNS server. + +This may be technically possible in the future, but it is not a priority for the project. + +## Can I set an interval to check for drifts between the PowerDNS server and the Kubernetes resources? + +The operator will not loop on each resource to check if it is in sync with the PowerDNS server. It will only react to events (create, update, delete) on the resources. If you update the resources, the operator will update the PowerDNS server accordingly. If you delete the resources, the operator will delete the resources from PowerDNS. + +This should be relatively easy to implement in the future if needed, allowing the user to choose a loop interval to remediate potential drifts. \ No newline at end of file diff --git a/docs/introduction/getting-started.md b/docs/introduction/getting-started.md new file mode 100644 index 0000000..6c5c32b --- /dev/null +++ b/docs/introduction/getting-started.md @@ -0,0 +1,50 @@ +# Getting Started + +PowerDNS Operator runs within your Kubernetes cluster as a deployment resource. It utilizes CustomResourceDefinitions (CRDs) to manage PowerDNS resources. The Operator communicates with the PowerDNS API to manage zones and records. + +## Pre-requisites + +Before you can install PowerDNS Operator, you need to have the following: + +* A Kubernetes cluster v1.29.0 or later +* A PowerDNS server v4.7 or later + +> Note: The PowerDNS API must be enabled and accessible from the Kubernetes cluster where the operator is running. + +## Installing with Kustomize + +Create the namespace and create a Secret containing the needed PowerDNS variables but you can also create the Secret using External Secrets or any other secret management tool. + +Theses secrets are used to configure the PowerDNS Operator to connect to the PowerDNS API. + +```bash +kubectl create namespace powerdns-operator-system +kubectl apply -f - <- + Manage PowerDNS from a Kubernetes cluster simple Custom Resources. +repo_url: https://github.com/Orange-OpenSource/PowerDNS-Operator +repo_name: PowerDNS Operator +copyright: Copyright (c) Orange Business Services SA +theme: + name: material + features: + - announce.dismiss # ?? + - content.code.copy + - content.tooltips + - navigation.indexes + - navigation.tabs + - navigation.expand + palette: + - media: "(prefers-color-scheme)" + toggle: + icon: material/link + name: Switch to light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: indigo + accent: indigo + toggle: + icon: material/toggle-switch + name: Switch to dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: black + accent: indigo + toggle: + icon: material/toggle-switch-off + name: Switch to system preference + font: + text: Roboto + code: Roboto Mono + favicon: assets/favicon.png + icon: + logo: logo +markdown_extensions: + - attr_list + - pymdownx.highlight + - pymdownx.superfences + - admonition + - pymdownx.snippets: + base_path: docs/snippets +nav: + - Introduction: + - Introduction: index.md + - Overview: introduction/overview.md + - Getting started: introduction/getting-started.md + - FAQ: introduction/faq.md + - Stability and Support: introduction/stability-support.md + - Guides: + - Zones: guides/zones.md + - RRsets: guides/rrsets.md