Full Code of bootc/netbox-chart for AI

main 96297979d1ba cached
79 files
416.2 KB
96.3k tokens
6 symbols
1 requests
Download .txt
Showing preview only (441K chars total). Download the full file or copy to clipboard to get everything.
Repository: bootc/netbox-chart
Branch: main
Commit: 96297979d1ba
Files: 79
Total size: 416.2 KB

Directory structure:
gitextract_jmg13inm/

├── .checkov.yaml
├── .editorconfig
├── .flake8
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   └── feature_request.yml
│   ├── dependabot.yml
│   ├── renovate.json
│   └── workflows/
│       ├── analysis.yml
│       ├── auto-merge.yml
│       ├── ci.yml
│       ├── lint.yml
│       ├── release.yml
│       └── test.yml
├── .gitignore
├── .markdownlint.yaml
├── LICENSE
├── README.md
├── charts/
│   ├── netbox/
│   │   ├── .helmignore
│   │   ├── Chart.yaml
│   │   ├── README.md
│   │   ├── ci/
│   │   │   ├── default-values.yaml
│   │   │   ├── ingress-metrics-values.yaml
│   │   │   └── ldap-values.yaml
│   │   ├── docs/
│   │   │   ├── auth.md
│   │   │   ├── extra.md
│   │   │   ├── migrate.md
│   │   │   └── prod.md
│   │   ├── files/
│   │   │   ├── configuration.py
│   │   │   └── ldap_config.py
│   │   ├── templates/
│   │   │   ├── NOTES.txt
│   │   │   ├── _helpers.tpl
│   │   │   ├── configmap.yaml
│   │   │   ├── cronjob.yaml
│   │   │   ├── deployment.yaml
│   │   │   ├── extra-list.yaml
│   │   │   ├── granian-servicemonitor.yaml
│   │   │   ├── hpa.yaml
│   │   │   ├── httproute.yaml
│   │   │   ├── ingress.yaml
│   │   │   ├── pdb.yaml
│   │   │   ├── pvc.yaml
│   │   │   ├── role.yaml
│   │   │   ├── rolebinding.yaml
│   │   │   ├── secret.yaml
│   │   │   ├── service.yaml
│   │   │   ├── serviceaccount.yaml
│   │   │   ├── servicemonitor.yaml
│   │   │   ├── tests/
│   │   │   │   └── test-connection.yaml
│   │   │   └── worker/
│   │   │       ├── deployment.yaml
│   │   │       ├── hpa.yaml
│   │   │       └── pdb.yaml
│   │   ├── values.schema.json
│   │   └── values.yaml
│   └── netbox-operator/
│       ├── .helmignore
│       ├── Chart.yaml
│       ├── README.md
│       ├── ci/
│       │   └── default-values.yaml
│       ├── crds/
│       │   ├── ipaddressclaims.yaml
│       │   ├── ipaddresses.yaml
│       │   ├── iprangeclaims.yaml
│       │   ├── ipranges.yaml
│       │   ├── prefixclaims.yaml
│       │   └── prefixes.yaml
│       ├── templates/
│       │   ├── NOTES.txt
│       │   ├── _helpers.tpl
│       │   ├── clusterrole.yaml
│       │   ├── clusterrolebinding.yaml
│       │   ├── deployment.yaml
│       │   ├── leaderelect/
│       │   │   ├── role.yaml
│       │   │   └── rolebinding.yaml
│       │   ├── secret.yaml
│       │   ├── serviceaccount.yaml
│       │   └── servicemonitor.yaml
│       └── values.yaml
├── config.yaml
└── pyproject.toml

================================================
FILE CONTENTS
================================================

================================================
FILE: .checkov.yaml
================================================
directory:
  - charts
skip-path:
  - /\w+/charts
evaluate-variables: true
framework:
  - helm
compact: true
quiet: true
soft-fail: true


================================================
FILE: .editorconfig
================================================
# editorconfig.org

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.py]
indent_size = 4

[*.md]
trim_trailing_whitespace = false


================================================
FILE: .flake8
================================================
[flake8]
max-line-length = 100
extend-ignore = E203, W503
per-file-ignores =
  charts/netbox/files/*:E131,E251,E266,E302,E305,E501,E722,F821


================================================
FILE: .gitattributes
================================================
# https://git-scm.com/docs/gitattributes

# Auto detect text files and perform LF normalization
* text=auto eol=lf

# Collapse generated and vendored files on GitHub
*.lock linguist-generated=true merge=ours

# Reduce conflicts on markdown files
*.md merge=union


================================================
FILE: .github/FUNDING.yml
================================================
# https://docs.github.com/articles/displaying-a-sponsor-button-in-your-repository

github:
  - RangerRick
  - LeoColomb


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: 🐛 Bug Report
description: Create a report about a malfunction of the Helm chart setup
labels:
  - bug
body:
  - type: markdown
    attributes:
      value: |
        > [!NOTE]
        > This form is only for reporting _reproducible bugs_ in a current NetBox
        > installation **using its Helm chart**.
        > If you're looking for assistance with using NetBox, please visit our
        > [discussion forum](https://github.com/netbox-community/netbox/discussions) instead.

        > [!TIP]
        > Please don't open an issue to open a PR. Just submit the PR, that's good enough.
  - type: input
    id: chart-version
    attributes:
      label: The Helm chart version
      description: What version of the Helm chart are you running?
      placeholder: netbox-5.0.0
    validations:
      required: true
  - type: textarea
    id: context-version
    attributes:
      label: Environment Versions
      description: What version of relevant tools are you using?
      render: text
      placeholder: |
        Kubernetes: 1.31
        Helm: 3.12
        FluxCD: 1.0
    validations:
      required: true
  - type: textarea
    id: chart-values-yml
    attributes:
      label: Custom chart values
      description: Please provide your custom values (`values.yaml`)
      render: yaml
      placeholder: |
        remoteAuth:
          enabled: true
          backends:
            - netbox.authentication.RemoteUserBackend
        ingress:
          enabled: true
    validations:
      required: true
  - type: textarea
    id: current-behavior
    attributes:
      label: Current Behavior & Steps to Reproduce
      description: Please describe what you did and how you think it misbehaved
      placeholder: I tried to … by doing …, but it …
    validations:
      required: true
  - type: textarea
    id: expected-behavior
    attributes:
      label: Expected Behavior
      description: What did you expect to happen?
      placeholder: I expected that … when I do …
    validations:
      required: true
  - type: textarea
    id: netbox-logs
    attributes:
      label: NetBox Logs
      description: Please paste the output of the deploy Pod logs
      render: text
      placeholder: |
        netbox_1  | ⚙️ Applying database migrations
        netbox_1  | 🧬 loaded config '/etc/netbox/config/configuration.py'
        netbox_1  | 🧬 loaded config '/etc/netbox/config/a.py'
        netbox_1  | 🧬 loaded config '/etc/netbox/config/extra.py'
        netbox_1  | 🧬 loaded config '/etc/netbox/config/logging.py'
        netbox_1  | 🧬 loaded config '/etc/netbox/config/plugins.py'
        ...
    validations:
      required: false


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
blank_issues_enabled: false
contact_links:
  - name: ❓ Question
    url: https://github.com/netbox-community/netbox/discussions
    about: The Github Discussions are the right place to ask questions about how to use or do certain things with NetBox.
  - name: 💬 Community Slack
    url: https://netdev.chat
    about: "Join #netbox-chart on the NetDev Community Slack for assistance with installation issues and other problems."


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
name: ✨ Feature Request
description: Propose a new NetBox feature or enhancement
labels:
  - enhancement
body:
  - type: markdown
    attributes:
      value: |
        > [!NOTE]
        > This form is only for submitting well-formed proposals to extend or modify
        > NetBox **Helm charts** in some way.
        > If you're trying to solve a problem but can't figure out how, or if
        > you still need time to work on the details of a proposed new feature, please start a
        > [discussion](https://github.com/netbox-community/netbox/discussions) instead.
  - type: textarea
    attributes:
      label: Proposed functionality
      description: |
        Describe in detail the new feature or behavior you are proposing. Include any specific changes
        to work flows, data models, and/or the user interface. The more detail you provide here, the
        greater chance your proposal has of being discussed. Feature requests which don't include an
        actionable implementation plan will be rejected.
    validations:
      required: true
  - type: textarea
    attributes:
      label: Use case
      description: |
        Explain how adding this functionality would benefit NetBox users when using its Helm chart.
        What need does it address?
    validations:
      required: true


================================================
FILE: .github/dependabot.yml
================================================
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
  - package-ecosystem: github-actions
    directory: "/"
    schedule:
      interval: daily


================================================
FILE: .github/renovate.json
================================================
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:recommended",
    ":configMigration",
    ":disableDependencyDashboard",
    "customManagers:helmChartYamlAppVersions"
  ],
  "labels": ["dependencies"],
  "rangeStrategy": "bump",
  "packageRules": [
    {
      "matchManagers": ["helmv3"],
      "versioning": "helm"
    },
    {
      "matchFileNames": ["charts/**"],
      "bumpVersions": [
        {
          "filePatterns": ["{{packageFileDir}}/Chart.{yaml,yml}"],
          "matchStrings": ["version:\\s(?<version>[^\\s]+)"],
          "bumpType": "{{#if isMajor}}minor{{else}}patch{{/if}}"
        }
      ]
    },
    {
      "matchUpdateTypes": ["!major"],
      "automerge": true
    }
  ],
  "kubernetes": {
    "managerFilePatterns": ["/^charts/.+\\.ya?ml$/"]
  },
  "github-actions": {
    "enabled": false
  }
}


================================================
FILE: .github/workflows/analysis.yml
================================================
# https://docs.github.com/actions

name: Analysis

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  schedule:
    - cron: "43 2 * * 6"
  workflow_dispatch:

jobs:
  checkov:
    name: Checkov
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write
    steps:
      - uses: actions/checkout@v6.0.2

      - name: Run Checkov scanner
        id: checkov
        uses: bridgecrewio/checkov-action@master

      - name: Upload scan results to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v4
        with:
          sarif_file: results.sarif


================================================
FILE: .github/workflows/auto-merge.yml
================================================
# https://docs.github.com/actions

name: Auto-merge

on:
  pull_request_target:
  workflow_call:

permissions:
  pull-requests: write
  contents: write

jobs:
  dependabot:
    name: Dependabot
    runs-on: ubuntu-latest
    if: ${{ github.actor == 'dependabot[bot]' }}
    steps:
      - name: Dependabot metadata
        id: dependabot-metadata
        uses: dependabot/fetch-metadata@v3.1.0

      - name: Approve a PR
        if: steps.dependabot-metadata.outputs.update-type != 'version-update:semver-major'
        run: gh pr review --approve "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GITHUB_TOKEN: ${{ github.token }}

      - name: Enable auto-merge for Dependabot PRs
        run: gh pr merge --auto --rebase "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GITHUB_TOKEN: ${{ github.token }}


================================================
FILE: .github/workflows/ci.yml
================================================
# yamllint disable rule:document-start
# https://docs.github.com/actions

name: CI

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  prepare:
    name: Prepare
    runs-on: ubuntu-latest
    outputs:
      changed: ${{ steps.list-changed.outputs.changed }}
    steps:
      - name: Checkout
        uses: actions/checkout@v6.0.2
        with:
          fetch-depth: 0

      - name: Set up chart-testing
        uses: helm/chart-testing-action@v2.8.0

      - name: Run chart-testing (list-changed)
        id: list-changed
        run: |
          changed=$(ct list-changed --config config.yaml)
          if [[ -n "$changed" ]]; then
            echo "changed=true" >> "$GITHUB_OUTPUT"
          fi

  test:
    name: Test
    if: needs.prepare.outputs.changed == 'true'
    needs:
      - prepare
    uses: ./.github/workflows/test.yml
    with:
      action-matrix: '["lint-and-install", "install --upgrade"]'
    secrets: inherit

  results:
    name: Status
    if: always()
    runs-on: ubuntu-latest
    needs:
      - prepare
      - test
    steps:
      - run: exit 1
        if: >-
          ${{
            contains(needs.*.result, 'failure') ||
            contains(needs.*.result, 'cancelled')
          }}

  release:
    name: Release
    if: github.ref == 'refs/heads/main'
    uses: ./.github/workflows/release.yml
    permissions:
      contents: write
      packages: write
      id-token: write
    secrets:
      GPG_KEY_BASE64: ${{ secrets.GPG_KEY_BASE64 }}
      GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}


================================================
FILE: .github/workflows/lint.yml
================================================
# https://docs.github.com/actions

name: Lint Code Base

on:
  push:
    branches-ignore: [main]
  pull_request:
    branches: [main]

permissions:
  contents: read
  packages: read
  statuses: write

jobs:
  build:
    name: Lint Code Base
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6.0.1
        with:
          fetch-depth: 0
          persist-credentials: false

      - name: Lint Code Base
        uses: super-linter/super-linter/slim@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0
        env:
          VALIDATE_ALL_CODEBASE: false
          DEFAULT_BRANCH: main
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          FIX_MARKDOWN_PRETTIER: false
          VALIDATE_BIOME_FORMAT: false
          VALIDATE_MARKDOWN_PRETTIER: false
          VALIDATE_JSCPD: false
          VALIDATE_PYTHON_MYPY: false
          VALIDATE_PYTHON_PYINK: false
          FILTER_REGEX_EXCLUDE: charts/[^/]+/[^/]+/.*\.yaml
          LINTER_RULES_PATH: /
          PYTHON_BLACK_CONFIG_FILE: pyproject.toml
          PYTHON_PYLINT_CONFIG_FILE: pyproject.toml
          PYTHON_ISORT_CONFIG_FILE: pyproject.toml
          PYTHON_RUFF_CONFIG_FILE: pyproject.toml


================================================
FILE: .github/workflows/release.yml
================================================
# yamllint disable rule:document-start
# https://docs.github.com/actions

name: Release

on:
  workflow_call:
    secrets:
      GPG_KEY_BASE64:
        required: true
        description: GPG key for signing
      GPG_PASSPHRASE:
        required: true
        description: passphrase for the signing key

jobs:
  publish:
    name: Publish
    runs-on: ubuntu-latest
    permissions:
      contents: write
      packages: write
      id-token: write
    steps:
      - name: Checkout
        uses: actions/checkout@v6.0.2
        with:
          fetch-depth: 0

      - name: Configure Git
        run: |
          git config user.name "$GITHUB_ACTOR"
          git config user.email "$GITHUB_ACTOR@users.noreply.github.com"

      - name: Prepare GPG key
        run: |
          gpg_dir="${HOME}/.cr-gpg"
          mkdir "$gpg_dir"
          keyring="$gpg_dir/secring.gpg"
          base64 -d <<< "$GPG_KEY_BASE64" > "$keyring"
          passphrase_file="$gpg_dir/passphrase"
          echo "$GPG_PASSPHRASE" > "$passphrase_file"
          echo "CR_PASSPHRASE_FILE=$passphrase_file" >> "$GITHUB_ENV"
          echo "CR_KEYRING=$keyring" >> "$GITHUB_ENV"
          echo "GNUPGHOME=${gpg_dir}"
        env:
          GPG_KEY_BASE64: "${{ secrets.GPG_KEY_BASE64 }}"
          GPG_PASSPHRASE: "${{ secrets.GPG_PASSPHRASE }}"

      - name: Install Helm
        uses: azure/setup-helm@v5.0.0

      - name: Add Helm repos
        run: helm repo add bitnami https://charts.bitnami.com/bitnami

      - name: Run chart-releaser
        uses: helm/chart-releaser-action@v1.7.0
        with:
          config: config.yaml
        env:
          CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v4
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Push charts to GitHub Container Registry
        run: |
          shopt -s nullglob
          for pkg in .cr-release-packages/*.tgz; do
            if [ -z "${pkg:-}" ]; then
              break
            fi
            helm push "${pkg}" "oci://ghcr.io/${GITHUB_REPOSITORY@L}"
          done


================================================
FILE: .github/workflows/test.yml
================================================
# yamllint disable rule:document-start
# https://docs.github.com/actions

name: Test

on:
  workflow_call:
    inputs:
      action-matrix:
        required: false
        default: '["install"]'
        type: string
        description: Matrix of actions to run

jobs:
  ct:
    name: Run chart-testing
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        action: ${{ fromJSON(inputs.action-matrix) }}
    steps:
      - name: Checkout
        uses: actions/checkout@v6.0.2
        with:
          fetch-depth: 0

      - name: Set up Helm
        uses: azure/setup-helm@v5.0.0

      - uses: actions/setup-python@v6
        if: startsWith(matrix.action, 'lint')
        with:
          python-version: 3.x

      - name: Set up chart-testing
        uses: helm/chart-testing-action@v2.8.0

      - name: Create kind cluster
        uses: helm/kind-action@v1.14.0
        if: contains(matrix.action, 'install')

      - name: Run chart-testing (${{ matrix.action }})
        run: ct ${{ matrix.action }} --config config.yaml --debug --helm-extra-set-args="$CT_HELM_EXTRA_SET_ARGS"
        env:
          CT_HELM_EXTRA_SET_ARGS: --set=host=${{ secrets.NETBOX_URL }} --set=auth.apiToken=${{ secrets.NETBOX_TOKEN }}


================================================
FILE: .gitignore
================================================
# https://git-scm.com/docs/gitignore

# General files
pkg/*
*.pyc
.project
/.bin
/_test/secrets/*.json

# macOS
._*
.DS_Store

# Editors and IDE
.idea/
.vscode/
*.swp
*.swo

# Emacs save files
*~
\#*\#
.\#*

# Vim-related files
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist

# Releases
dist/

# Chart dependencies
**/charts/*.tgz
values-*.yaml
.history
/public


================================================
FILE: .markdownlint.yaml
================================================
default: true
MD013: false
MD031: false
MD060: false


================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
# Netbox Helm Charts

> The official [Helm](https://helm.sh) charts repository for [Netbox](https://netbox.dev).

[![Build Status](https://github.com/netbox-community/netbox-chart/actions/workflows/ci.yml/badge.svg)](https://github.com/netbox-community/netbox-chart/actions/workflows/ci.yml)
[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/netbox)](https://artifacthub.io/packages/search?repo=netbox)

## About

This Git repository houses the official Helm charts for Netbox.

Do you have any questions?
Before opening an issue on GitHub, please join [our Slack](https://netdev.chat/)
and ask for help in the [`#netbox-chart`](https://netdev-community.slack.com/archives/C01Q6B100R2) channel.

|                        Chart                        |                                                                                                                    Version                                                                                                                     |
| :-------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|          [`netbox/netbox`](charts/netbox/)          |          [![Chart Version](https://img.shields.io/badge/dynamic/json?label=netbox&query=version&url=https%3A%2F%2Fartifacthub.io%2Fapi%2Fv1%2Fpackages%2Fhelm%2Fnetbox%2Fnetbox)](https://artifacthub.io/packages/helm/netbox/netbox)          |
| [`netbox/netbox-operator`](charts/netbox-operator/) | [![Chart Version](https://img.shields.io/badge/dynamic/json?label=netbox-operator&query=version&url=https%3A%2F%2Fartifacthub.io%2Fapi%2Fv1%2Fpackages%2Fhelm%2Fnetbox%2Fnetbox-operator)](https://artifacthub.io/packages/helm/netbox/netbox-operator) |

## Quickstart

```shell
helm install my-release oci://ghcr.io/netbox-community/netbox-chart/netbox
```

See docs on your preferred sources:

- [Charts docs on Artifact Hub](https://artifacthub.io/packages/search?org=netbox)
- [Charts respective readmes](charts)
- [Charts discovery](https://helm.sh/docs/helm/helm_search/)
  ```sh
  helm search hub netbox
  ```
- [Charts repository](https://helm.sh/docs/helm/helm_repo/)
  ```sh
  helm repo add netbox https://charts.netbox.oss.netboxlabs.com/
  ```

## License

This project is licensed under [Apache License, Version 2.0](LICENSE).


================================================
FILE: charts/netbox/.helmignore
================================================
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

# OWNERS file for Kubernetes
OWNERS
# example production yaml
values-production.yaml
# ci files
ci/
# docs files
docs/


================================================
FILE: charts/netbox/Chart.yaml
================================================
apiVersion: v2
name: netbox
version: 8.2.7
# renovate: image=ghcr.io/netbox-community/netbox
appVersion: "v4.6.0"
type: application
kubeVersion: ^1.25.0-0
description: IP address management (IPAM) and data center infrastructure management (DCIM) tool
home: https://netbox.dev/
icon: https://raw.githubusercontent.com/netbox-community/netbox/main/docs/netbox_logo_light.svg
sources:
  - https://github.com/netbox-community/netbox-chart
  - https://github.com/netbox-community/netbox
maintainers:
  - name: netbox-community
    url: https://github.com/netbox-community
  - name: bootc
    url: https://github.com/bootc
dependencies:
  - name: common
    repository: oci://registry-1.docker.io/bitnamicharts
    version: ^2.38.0
    tags:
      - bitnami-common
  - name: postgresql
    version: ^18.6.3
    repository: oci://registry-1.docker.io/bitnamicharts
    condition: postgresql.enabled
  - name: valkey
    version: ^5.6.1
    repository: oci://registry-1.docker.io/bitnamicharts
    condition: valkey.enabled
annotations:
  artifacthub.io/images: |
    - name: netbox
      image: ghcr.io/netbox-community/netbox:v4.6.0
    - name: busybox
      image: docker.io/busybox:1.37.0
    - name: kubectl
      image: docker.io/rancher/kubectl:v1.36.0
  artifacthub.io/license: Apache-2.0
  artifacthub.io/links: |
    - name: Upstream Project
      url: https://github.com/netbox-community/netbox
  artifacthub.io/changes: |
    - kind: changed
      description: New release
      links:
        - name: Changelog on GitHub Releases
          url: https://github.com/netbox-community/netbox-chart/releases?q=netbox-


================================================
FILE: charts/netbox/README.md
================================================
# NetBox

[NetBox](https://netbox.dev) is an IP address management (IPAM) and
data center infrastructure management (DCIM) tool.

## TL;DR

```shell
helm install netbox oci://ghcr.io/netbox-community/netbox-chart/netbox
```

> [!tip]
> Please see [Production Considerations](docs/prod.md) guide before using this chart for real.

## Prerequisites

- Kubernetes [1.25+](https://kubernetes.io/releases/)
- Helm [3.10+](https://helm.sh/docs/topics/version_skew/)

## Installing the Chart

To install the chart with the release name `my-release` and default configuration:

```shell
helm install my-release oci://ghcr.io/netbox-community/netbox-chart/netbox
```

## Documentation

- [Production Considerations](docs/prod.md)
- [Authentication Options](docs/auth.md)
- [Extra Configuration](docs/extra.md)
- [Migration Guide](docs/migrate.md)

## Configuration

The following table lists the configurable parameters for this chart and their default values.

<!-- prettier-ignore-start -->

| Parameter                                       | Description                                                         | Default                                      |
| ------------------------------------------------|---------------------------------------------------------------------|----------------------------------------------|
| `global.imageRegistry`                          | Netbox and subchart image registry for pulling container images     | `""`                                         |
| `global.imagePullSecrets`                       | Netbox and subchart registry secret names as an array               | `[]`                                         |
| `global.storageClass`                           | Netbox and subchart default StorageClass for Persistent Volume(s)   | `""`                                         |
| `replicaCount`                                  | The desired number of NetBox pods                                   | `1`                                          |
| `image.registry`                                | NetBox container image registry                                     | `ghcr.io`                                    |
| `image.repository`                              | NetBox container image repository                                   | `netboxcommunity/netbox`                     |
| `image.tag`                                     | NetBox container image tag                                          | `""`                                         |
| `image.pullPolicy`                              | NetBox container image pull policy                                  | `IfNotPresent`                               |
| `superuser.name`                                | Initial super-user account to create                                | `admin`                                      |
| `superuser.email`                               | Email address for the initial super-user account                    | `admin@example.com`                          |
| `superuser.password`                            | Password for the initial super-user account                         | `admin`                                      |
| `superuser.apiToken`                            | API token created for the initial super-user account                | `0123456789abcdef0123456789abcdef01234567`   |
| `superuser.existingSecret`                      | Use an existing Kubernetes `Secret` for secret values               | `""`                                         |
| `allowedHosts`                                  | List of valid FQDNs for this NetBox instance                        | `["*"]`                                      |
| `admins`                                        | List of admins to email about critical errors                       | `[]`                                         |
| `allowTokenRetrieval`                           | Permit the retrieval of API tokens after their creation             | `false`                                      |
| `authPasswordValidators`                        | Configure validation of local user account passwords                | `[]`                                         |
| `allowedUrlSchemes`                             | URL schemes that are allowed within links in NetBox                 | *see `values.yaml`*                          |
| `banner.top`                                    | Banner text to display at the top of every page                     | `""`                                         |
| `banner.bottom`                                 | Banner text to display at the bottom of every page                  | `""`                                         |
| `banner.login`                                  | Banner text to display on the login page                            | `""`                                         |
| `basePath`                                      | Base URL path if accessing NetBox within a directory                | `""`                                         |
| `changelogRetention`                            | Maximum number of days to retain logged changes (0 = forever)       | `90`                                         |
| `customValidators`                              | Custom validators for NetBox field values                           | `{}`                                         |
| `defaultUserPreferences`                        | Default preferences for newly created user accounts                 | `{}`                                         |
| `cors.originAllowAll`                           | [CORS]: allow all origins                                           | `false`                                      |
| `cors.originWhitelist`                          | [CORS]: list of origins authorised to make cross-site HTTP requests | `[]`                                         |
| `cors.originRegexWhitelist`                     | [CORS]: list of regular expression matching authorised origins      | `[]`                                         |
| `csrf.cookieName`                               | Name of the CSRF authentication cookie                              | `csrftoken`                                  |
| `csrf.trustedOrigins`                           | A list of trusted origins for unsafe (e.g. POST) requests           | `[]`                                         |
| `dataUploadMaxMemorySize`                       | The maximum size (in bytes) of an incoming HTTP request             | `2621440`                                    |
| `debug`                                         | Enable NetBox debugging (NOT for production use)                    | `false`                                      |
| `defaultLanguage`                               | Set the default preferred language/locale                           | `en-us`                                      |
| `dbWaitDebug`                                   | Show details of errors that occur when applying migrations          | `false`                                      |
| `email.server`                                  | SMTP server to use to send emails                                   | `localhost`                                  |
| `email.port`                                    | TCP port to connect to the SMTP server on                           | `25`                                         |
| `email.username`                                | Optional username for SMTP authentication                           | `""`                                         |
| `email.password`                                | Password for SMTP authentication (see also `existingSecret`)        | `""`                                         |
| `email.useSSL`                                  | Use SSL when connecting to the server                               | `false`                                      |
| `email.useTLS`                                  | Use TLS when connecting to the server                               | `false`                                      |
| `email.sslCertFile`                             | SMTP SSL certificate file path (e.g. in a mounted volume)           | `""`                                         |
| `email.sslKeyFile`                              | SMTP SSL key file path (e.g. in a mounted volume)                   | `""`                                         |
| `email.timeout`                                 | Timeout for SMTP connections, in seconds                            | `10`                                         |
| `email.from`                                    | Sender address for emails sent by NetBox                            | `""`                                         |
| `enforceGlobalUnique`                           | Enforce unique IP space in the global table (not in a VRF)          | `true`                                      |
| `exemptViewPermissions`                         | A list of models to exempt from the enforcement of view permissions | `[]`                                         |
| `fieldChoices`                                  | Configure custom choices for certain built-in fields                | `{}`                                         |
| `fileUploadMaxMemorySize`                       | The maximum amount (in bytes) of uploaded data that will be held in memory before being written to the filesystem  | `2621440` |
| `graphQlEnabled`                                | Enable the GraphQL API                                              | `true`                                       |
| `httpProxies`                                   | HTTP proxies NetBox should use when sending outbound HTTP requests  | `null`                                       |
| `internalIPs`                                   | IP addresses recognized as internal to the system                   | `['127.0.0.1', '::1']`                       |
| `jobRetention`                                  | The number of days to retain job results (scripts and reports)      | `90`                                         |
| `logging`                                       | Custom Django logging configuration                                 | `{}`                                         |
| `loginPersistence`                              | Enables users to remain authenticated to NetBox indefinitely        | `false`                                      |
| `loginRequired`                                 | Permit only logged-in users to access NetBox                        | `false` (unauthenticated read-only access)   |
| `loginTimeout`                                  | How often to re-authenticate users                                  | `1209600` (14 days)                          |
| `logoutRedirectUrl`                             | View name or URL to which users are redirected after logging out    | `home`                                       |
| `maintenanceMode`                               | Display a "maintenance mode" banner on every page                   | `false`                                      |
| `mapsUrl`                                       | The URL to use when mapping physical addresses or GPS coordinates   | `https://maps.google.com/?q=`                |
| `maxPageSize`                                   | Maximum number of objects that can be returned by a single API call | `1000`                                       |
| `storages`                                      | `django-storages` backends configuration                            | `{}`                                         |
| `paginateCount`                                 | The default number of objects to display per page in the web UI     | `50`                                         |
| `plugins`                                       | Additional plugins to load into NetBox                              | `[]`                                         |
| `pluginsConfig`                                 | Configuration for the additional plugins                            | `{}`                                         |
| `powerFeedDefaultAmperage`                      | Default amperage value for new power feeds                          | `15`                                         |
| `powerFeedMaxUtilisation`                       | Default maximum utilisation percentage for new power feeds          | `80`                                         |
| `powerFeedDefaultVoltage`                       | Default voltage value for new power feeds                           | `120`                                        |
| `preferIPv4`                                    | Prefer devices' IPv4 address when determining their primary address | `false`                                      |
| `rackElevationDefaultUnitHeight`                | Rack elevation default height in pixels                             | `22`                                         |
| `rackElevationDefaultUnitWidth`                 | Rack elevation default width in pixels                              | `220`                                        |
| `remoteAuth.enabled`                            | Enable remote authentication support                                | `false`                                      |
| `remoteAuth.backends`                           | Remote authentication backend classes                               | `[netbox.authentication.RemoteUserBackend]`  |
| `remoteAuth.header`                             | The name of the HTTP header which conveys the username              | `HTTP_REMOTE_USER`                           |
| `remoteAuth.userFirstName`                      | HTTP header which contains the user's first name                    | `HTTP_REMOTE_USER_FIRST_NAME`                |
| `remoteAuth.userLastName`                       | HTTP header which contains the user's last name                     | `HTTP_REMOTE_USER_LAST_NAME`                 |
| `remoteAuth.userEmail`                          | HTTP header which contains the user's email address                 | `HTTP_REMOTE_USER_EMAIL`                     |
| `remoteAuth.autoCreateUser`                     | Enables the automatic creation of new users                         | `false`                                      |
| `remoteAuth.autoCreateGroups`                   | Enables the automatic creation of new groups                        | `false`                                      |
| `remoteAuth.defaultGroups`                      | A list of groups to assign to newly created users                   | `[]`                                         |
| `remoteAuth.defaultPermissions`                 | A list of permissions to assign newly created users                 | `{}`                                         |
| `remoteAuth.groupSyncEnabled`                   | Sync remote user groups from an HTTP header set by a reverse proxy  | `false`                                      |
| `remoteAuth.groupHeader`                        | The name of the HTTP header which conveys the groups to which the user belongs | `HTTP_REMOTE_USER_GROUP`          |
| `remoteAuth.superuserGroups`                    | The list of groups that promote an remote User to Superuser on login| `[]`                                         |
| `remoteAuth.superusers`                         | The list of users that get promoted to Superuser on login           | `[]`                                         |
| `remoteAuth.staffGroups`                        | The list of groups that promote an remote User to Staff on login    | `[]`                                         |
| `remoteAuth.staffUsers`                         | The list of users that get promoted to Staff on login               | `[]`                                         |
| `remoteAuth.groupSeparator`                     | The Seperator upon which `remoteAuth.groupHeader` gets split into individual groups | `\|`                        |
| `remoteAuth.ldap.serverUri`                     | see [django-auth-ldap](https://django-auth-ldap.readthedocs.io)     | `""`                                         |
| `remoteAuth.ldap.startTls`                      | if StarTLS should be used                                           | *see values.yaml*                            |
| `remoteAuth.ldap.ignoreCertErrors`              | if Certificate errors should be ignored                             | *see values.yaml*                            |
| `remoteAuth.ldap.caCertDir`                     | CA certificate directory                                            | *see auth.md*                                |
| `remoteAuth.ldap.caCertData`                    | CA certificate data                                                 | *see auth.md*                                |
| `remoteAuth.ldap.bindDn`                        | Distinguished Name to bind with                                     | `""`                                         |
| `remoteAuth.ldap.bindPassword`                  | Password for bind DN                                                | `""`                                         |
| `remoteAuth.ldap.userDnTemplate`                | see [AUTH_LDAP_USER_DN_TEMPLATE](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-user-dn-template) | *see values.yaml* |
| `remoteAuth.ldap.userSearchBaseDn`              | see base_dn of [django_auth_ldap.config.LDAPSearch](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#django_auth_ldap.config.LDAPSearch) | *see values.yaml* |
| `remoteAuth.ldap.userSearchAttr`                | User attribute name for user search                                 | `sAMAccountName`                             |
| `remoteAuth.ldap.groupSearchBaseDn`             | base DN for group search                                            | *see values.yaml*                            |
| `remoteAuth.ldap.groupSearchClass`              | [django-auth-ldap](https://django-auth-ldap.readthedocs.io) for group search | `group`                             |
| `remoteAuth.ldap.groupType`                     | see [AUTH_LDAP_GROUP_TYPE](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-group-type) | `GroupOfNamesType` |
| `remoteAuth.ldap.requireGroupDn`                | DN of a group that is required for login                            | `null`                                       |
| `remoteAuth.ldap.findGroupPerms`                | see [AUTH_LDAP_FIND_GROUP_PERMS](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-find-group-perms) | true |
| `remoteAuth.ldap.mirrorGroups`                  | see [AUTH_LDAP_MIRROR_GROUPS](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-mirror-groups) | `null` |
| `remoteAuth.ldap.cacheTimeout`                  | see [AUTH_LDAP_MIRROR_GROUPS_EXCEPT](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-mirror-groups-except) | `null` |
| `remoteAuth.ldap.isAdminDn`                     | required DN to be able to login in Admin-Backend, "is_staff"-Attribute of [AUTH_LDAP_USER_FLAGS_BY_GROUP](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-user-flags-by-group) | *see values.yaml* |
| `remoteAuth.ldap.isSuperUserDn`                 | required DN to receive SuperUser privileges, "is_superuser"-Attribute of [AUTH_LDAP_USER_FLAGS_BY_GROUP](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-user-flags-by-group) | *see values.yaml* |
| `remoteAuth.ldap.attrFirstName`                 | first name attribute of users, "first_name"-Attribute of [AUTH_LDAP_USER_ATTR_MAP](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-user-attr-map) | `givenName` |
| `remoteAuth.ldap.attrLastName`                  | last name attribute of users, "last_name"-Attribute of [AUTH_LDAP_USER_ATTR_MAP](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-user-attr-map) | `sn` |
| `remoteAuth.ldap.attrMail`                      | mail attribute of users, "email_name"-Attribute of [AUTH_LDAP_USER_ATTR_MAP](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-user-attr-map) | `mail` |
| `releaseCheck.url`                              | Release check URL (GitHub API URL; see `values.yaml`)               | `null` (disabled by default)                 |
| `rqDefaultTimeout`                              | Maximum execution time for background tasks, in seconds             | `300` (5 minutes)                            |
| `sessionCookieName`                             | The name to use for the session cookie                              | `"sessionid"`                                |
| `enableLocalization`                            | Localization                                                        | `false`                                      |
| `timeZone`                                      | The time zone NetBox will use when dealing with dates and times     | `UTC`                                        |
| `dateFormat`                                    | Django date format for long-form date strings                       | `"N j, Y"`                                   |
| `shortDateFormat`                               | Django date format for short-form date strings                      | `"Y-m-d"`                                    |
| `timeFormat`                                    | Django date format for long-form time strings                       | `"g:i a"`                                    |
| `metrics.granian.enabled`                       | Enable Granian metrics                                              | `true`                                       |
| `metrics.granian.serviceMonitor.enabled`        | Whether to enable a [ServiceMonitor](https://prometheus-operator.dev/docs/operator/design/#servicemonitor) for Granian metrics | `false`                                      |
| `metrics.granian.serviceMonitor.additionalLabels`| Additonal labels to apply to the ServiceMonitor                     | `{}`                                         |
| `metrics.granian.serviceMonitor.honorLabels`    | honorLabels chooses the metric's labels on collisions               | `false`                                      |
| `metrics.granian.serviceMonitor.interval`       | Interval at which metrics should be scraped                         | `""`                                         |
| `metrics.granian.serviceMonitor.scrapeTimeout`  | Timeout duration for scraping metrics                               | `""`                                         |
| `metrics.granian.serviceMonitor.metricRelabelings`| Specify additional relabeling of metrics                            | `[]`                                         |
| `metrics.granian.serviceMonitor.relabelings`    | Specify general relabeling                                          | `[]`                                         |
| `metrics.granian.serviceMonitor.selector`       | Prometheus instance selector labels                                 | `{}`                                         |
| `metrics.enabled`                               | Expose Prometheus metrics at the `/metrics` HTTP endpoint           | `false`                                      |
| `metrics.serviceMonitor.enabled`                | Whether to enable a [ServiceMonitor](https://prometheus-operator.dev/docs/operator/design/#servicemonitor) for Netbox | `false`                                      |
| `metrics.serviceMonitor.additionalLabels`       | Additonal labels to apply to the ServiceMonitor                     | `{}`                                         |
| `metrics.serviceMonitor.honorLabels`            | honorLabels chooses the metric's labels on collisions               | `false`                                      |
| `metrics.serviceMonitor.interval`               | Interval at which metrics should be scraped                         | `""`                                         |
| `metrics.serviceMonitor.scrapeTimeout`          | Timeout duration for scraping metrics                               | `""`                                         |
| `metrics.serviceMonitor.metricRelabelings`      | Specify additional relabeling of metrics                            | `[]`                                         |
| `metrics.serviceMonitor.relabelings`            | Specify general relabeling                                          | `[]`                                         |
| `metrics.serviceMonitor.selector`               | Prometheus instance selector labels                                 | `{}`                                         |
| `shortTimeFormat`                               | Django date format for short-form time strings                      | `"H:i:s"`                                    |
| `dateTimeFormat`                                | Django date format for long-form date and time strings              | `"N j, Y g:i a"`                             |
| `shortDateTimeFormat`                           | Django date format for short-form date and time strongs             | `"Y-m-d H:i"`                                |
| `extraConfig`                                   | Additional NetBox configuration (see `values.yaml`)                 | `[]`                                         |
| `secretKey`                                     | Django secret key used for sessions and password reset tokens       | `""` (generated)                             |
| `existingSecret`                                | Use an existing Kubernetes `Secret` for secret values (see below)   | `""` (use individual chart values)           |
| `postgresql.enabled`                            | Deploy PostgreSQL using bundled Bitnami PostgreSQL chart            | `true`                                       |
| `postgresql.auth.username`                      | Username to create for NetBox in bundled PostgreSQL instance        | `netbox`                                     |
| `postgresql.auth.database`                      | Database to create for NetBox in bundled PostgreSQL instance        | `netbox`                                     |
| `postgresql.*`                                  | Values under this key are passed to the bundled PostgreSQL chart    | n/a                                          |
| `externalDatabase.host`                         | PostgreSQL host to use when `postgresql.enabled` is `false`         | `localhost`                                  |
| `externalDatabase.port`                         | Port number for external PostgreSQL                                 | `5432`                                       |
| `externalDatabase.database`                     | Database name for external PostgreSQL                               | `netbox`                                     |
| `externalDatabase.username`                     | Username for external PostgreSQL                                    | `netbox`                                     |
| `externalDatabase.password`                     | Password for external PostgreSQL (see also `existingSecret`)        | `""`                                         |
| `externalDatabase.existingSecretName`           | Fetch password for external PostgreSQL from a different `Secret`    | `""`                                         |
| `externalDatabase.existingSecretKey`            | Key to fetch the password in the above `Secret`                     | `postgresql-password`                        |
| `externalDatabase.connMaxAge`                   | The lifetime of a database connection, as an integer of seconds     | `300`                                        |
| `externalDatabase.disableServerSideCursors`     | Disable the use of server-side cursors transaction pooling          | `false`                                      |
| `externalDatabase.options`                      | Additional PostgreSQL client parameters                             | `{}`                                            |
| `valkey.enabled`                                | Deploy Valkey using bundled Bitnami Valkey chart                    | `true`                                       |
| `valkey.*`                                      | Values under this key are passed to the bundled Valkey chart        | n/a                                          |
| `tasksDatabase.database`                           | KV database number used for NetBox task queue                       | `0`                                          |
| `tasksDatabase.ssl`                                | Enable SSL when connecting to KV                                    | `false`                                      |
| `tasksDatabase.insecureSkipTlsVerify`              | Skip TLS certificate verification when connecting to KV             | `false`                                      |
| `tasksDatabase.caCertPath`                         | Path to CA certificates bundle for KV (needs mounting manually)     | `""`                                         |
| `tasksDatabase.host`                               | KV host to use when `valkey.enabled` is `false`                     | `"netbox-kv"`                             |
| `tasksDatabase.port`                               | Port number for external KV                                         | `6379`                                       |
| `tasksDatabase.sentinels`                          | List of sentinels in `host:port` form (`host` and `port` not used)  | `[]`                                         |
| `tasksDatabase.sentinelService`                    | Sentinel master service name                                        | `"netbox-kv"`                             |
| `tasksDatabase.sentinelTimeout`                    | Sentinel connection timeout, in seconds                             | `300` (5 minutes)                            |
| `tasksDatabase.username`                           | Username for external KV                                            | `""`                                         |
| `tasksDatabase.password`                           | Password for external KV (see also `existingSecret`)                | `""`                                         |
| `tasksDatabase.existingSecretName`                 | Fetch password for external KV from a different `Secret`            | `""`                                         |
| `tasksDatabase.existingSecretKey`                  | Key to fetch the password in the above `Secret`                     | `tasks-password`                             |
| `cachingDatabase.database`                         | KV database number used for caching views                           | `1`                                          |
| `cachingDatabase.ssl`                              | Enable SSL when connecting to KV                                    | `false`                                      |
| `cachingDatabase.insecureSkipTlsVerify`            | Skip TLS certificate verification when connecting to KV             | `false`                                      |
| `cachingDatabase.caCertPath`                       | Path to CA certificates bundle for KV (needs mounting manually)     | `""`                                         |
| `cachingDatabase.host`                             | KV host to use when `valkey.enabled` is `false`                     | `"netbox-kv"`                             |
| `cachingDatabase.port`                             | Port number for external KV                                         | `6379`                                       |
| `cachingDatabase.sentinels`                        | List of sentinels in `host:port` form (`host` and `port` not used)  | `[]`                                         |
| `cachingDatabase.sentinelService`                  | Sentinel master service name                                        | `"netbox-kv"`                             |
| `cachingDatabase.sentinelTimeout`                  | Sentinel connection timeout, in seconds                             | `300` (5 minutes)                            |
| `cachingDatabase.username`                         | Username for external KV                                            | `""`                                         |
| `cachingDatabase.password`                         | Password for external KV (see also `existingSecret`)                | `""`                                         |
| `cachingDatabase.existingSecretName`               | Fetch password for external KV from a different `Secret`            | `""`                                         |
| `cachingDatabase.existingSecretKey`                | Key to fetch the password in the above `Secret`                     | `cache-password`                             |
| `imagePullSecrets`                              | List of `Secret` names containing private registry credentials      | `[]`                                         |
| `nameOverride`                                  | Override the application name (`netbox`) used throughout the chart  | `""`                                         |
| `fullnameOverride`                              | Override the full name of resources created as part of the release  | `""`                                         |
| `serviceAccount.create`                         | Create a ServiceAccount for NetBox                                  | `true`                                       |
| `serviceAccount.annotations`                    | Annotations to add to the service account                           | `{}`                                         |
| `serviceAccount.name`                           | The name of the service account to use                              | `""` (use the fullname)                      |
| `serviceAccount.imagePullSecrets`               | Add an imagePullSecrets attribute to the serviceAccount             | `""`                                         |
| `serviceAccount.automountServiceAccountToken`   | Whether to automatically mount the token in the containers using this serviceAccount or not | `false`              |
| `persistence.enabled`                           | Enable storage persistence for uploaded media (images)              | `true`                                       |
| `persistence.existingClaim`                     | Use an existing `PersistentVolumeClaim` instead of creating one     | `""`                                         |
| `persistence.subPath`                           | Mount a sub-path of the volume into the container, not the root     | `""`                                         |
| `persistence.storageClass`                      | Set the storage class of the PVC (use `-` to disable provisioning)  | `""`                                         |
| `persistence.selector`                          | Set the selector for PVs, if desired                                | `{}`                                         |
| `persistence.accessMode`                        | Access mode for the volume                                          | `ReadWriteOnce`                              |
| `persistence.size`                              | Size of persistent volume to request                                | `1Gi`                                        |
| `reportsPersistence.enabled`                    | Enable storage persistence for NetBox reports                       | `false`                                      |
| `reportsPersistence.existingClaim`              | Use an existing `PersistentVolumeClaim` instead of creating one     | `""`                                         |
| `reportsPersistence.subPath`                    | Mount a sub-path of the volume into the container, not the root     | `""`                                         |
| `reportsPersistence.storageClass`               | Set the storage class of the PVC (use `-` to disable provisioning)  | `""`                                         |
| `reportsPersistence.selector`                   | Set the selector for PVs, if desired                                | `{}`                                         |
| `reportsPersistence.accessMode`                 | Access mode for the volume                                          | `ReadWriteOnce`                              |
| `reportsPersistence.size`                       | Size of persistent volume to request                                | `1Gi`                                        |
| `scriptsPersistence.enabled`                    | Enable storage persistence for NetBox reports                       | `false`                                      |
| `scriptsPersistence.existingClaim`              | Use an existing `PersistentVolumeClaim` instead of creating one     | `""`                                         |
| `scriptsPersistence.subPath`                    | Mount a sub-path of the volume into the container, not the root     | `""`                                         |
| `scriptsPersistence.storageClass`               | Set the storage class of the PVC (use `-` to disable provisioning)  | `""`                                         |
| `scriptsPersistence.selector`                   | Set the selector for PVs, if desired                                | `{}`                                         |
| `scriptsPersistence.accessMode`                 | Access mode for the volume                                          | `ReadWriteOnce`                              |
| `scriptsPersistence.size`                       | Size of persistent volume to request                                | `1Gi`                                        |
| `podAnnotations`                                | Additional annotations for NetBox pods                              | `{}`                                         |
| `podLabels`                                     | Additional labels for NetBox pods                                   | `{}`                                         |
| `podSecurityContext`                            | Security context for NetBox pods                                    | *see `values.yaml`*                          |
| `securityContext`                               | Security context for NetBox containers                              | *see `values.yaml`*                          |
| `service.type`                                  | Type of `Service` resource to create                                | `ClusterIP`                                  |
| `service.port`                                  | Port number for the service                                         | `80`                                         |
| `service.nodePort`                              | The port used on the node when `service.type` is NodePort           | `""`                                         |
| `service.clusterIP`                             | The cluster IP address assigned to the service                      | `""`                                         |
| `service.clusterIPs`                            | A list of cluster IP addresses assigned to the service              | `[]`                                         |
| `service.externalIPs`                           | A list of external IP addresses aliased to this service             | `[]`                                         |
| `service.externalTrafficPolicy`                 | Policy for routing external traffic                                 | `Cluster`                                    |
| `service.ipFamilyPolicy`                        | Represents the dual-stack-ness of the service                       | `""`                                         |
| `service.loadBalancerIP`                        | Request a specific IP address when `service.type` is `LoadBalancer` | `""`                                         |
| `service.loadBalancerSourceRanges`              | A list of allowed IP ranges when `service.type` is `LoadBalancer`   | `[]`                                         |
| `service.loadBalancerClass`                     | Load Balancer class if `service.type` is `LoadBalancer`             | `""`                                         |
| `service.sessionAffinity`                       | Control where client requests go, to the same pod or round-robin    | `None`                                       |
| `service.sessionAffinityConfig`                 | Additional settings for the sessionAffinity                         | `{}`                                         |
| `ingress.enabled`                               | Create an `Ingress` resource for accessing NetBox                   | `false`                                      |
| `ingress.className`                             | Use a named IngressClass                                            | `""`                                         |
| `ingress.annotations`                           | Extra annotations to apply to the `Ingress` resource                | `{}`                                         |
| `ingress.hosts`                                 | List of hosts and paths to map to the service (see `values.yaml`)   | `[{host:"chart-example.local",paths:["/"]}]` |
| `ingress.tls`                                   | TLS settings for the `Ingress` resource                             | `[]`                                         |
| `httpRoute.enabled`                             | Create an `HTTPRoute` resource for Gateway API                      | `false`                                      |
| `httpRoute.annotations`                         | Extra annotations to apply to the `HTTPRoute` resource              | `{}`                                         |
| `httpRoute.parentRefs`                          | References to the parent Gateway(s) for the `HTTPRoute`             | `[]`                                         |
| `httpRoute.hostnames`                           | Hostnames that the `HTTPRoute` should match                         | `[]`                                         |
| `httpRoute.filters`                             | Optional filters to apply to the route                              | `[]`                                         |
| `resources`                                     | Configure resource requests or limits for NetBox                    | `{}`                                         |
| `automountServiceAccountToken`                  | Whether to automatically mount the serviceAccount token in the main container or not | `false`                     |
| `priorityClassName`                             | Pods' priorityClassName                                             | `""`                                         |
| `schedulerName`                                 | Name of the k8s scheduler (other than default) for pods             | `""`                                         |
| `terminationGracePeriodSeconds`                 | Seconds pods need to terminate gracefully                           | `""`                                         |
| `topologySpreadConstraints`                     | Configure Pod Topology Spread Constraints for NetBox                | `[]`                                         |
| `livenessProbe.enabled`                         | Enable Kubernetes livenessProbe, see [liveness probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-command) | *see `values.yaml`* |
| `livenessProbe.initialDelaySeconds`             | Number of seconds                                                   |  *see `values.yaml`*                         |
| `livenessProbe.timeoutSeconds`                  | Number of seconds                                                   |  *see `values.yaml`*                         |
| `livenessProbe.periodSeconds`                   | Number of seconds                                                   |  *see `values.yaml`*                         |
| `livenessProbe.successThreshold`                | Number of seconds                                                   |  *see `values.yaml`*                         |
| `readinessProbe.enabled`                        | Enable Kubernetes readinessProbe, see [readiness probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes) | *see `values.yaml`* |
| `readinessProbe.initialDelaySeconds`            | Number of seconds                                                   |  *see `values.yaml`*                         |
| `readinessProbe.timeoutSeconds`                 | Number of seconds                                                   |  *see `values.yaml`*                         |
| `readinessProbe.periodSeconds`                  | Number of seconds                                                   |  *see `values.yaml`*                         |
| `readinessProbe.successThreshold`               | Number of seconds                                                   |  *see `values.yaml`*                         |
| `lifecycleHooks`                                | Automate configuration before or after container startup            | `{}`                                         |
| `startupProbe.enabled`                          | Enable Kubernetes startupProbe, see [startup probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes) | *see `values.yaml`* |
| `startupProbe.initialDelaySeconds`              | Number of seconds                                                   |  *see `values.yaml`*                         |
| `startupProbe.timeoutSeconds`                   | Number of seconds                                                   |  *see `values.yaml`*                         |
| `startupProbe.periodSeconds`                    | Number of seconds                                                   |  *see `values.yaml`*                         |
| `startupProbe.successThreshold`                 | Number of seconds                                                   |  *see `values.yaml`*                         |
| `init.image.registry`                           | Init container image registry                                       | `ghcr.io`                                    |
| `init.image.repository`                         | Init container image repository                                     | `busybox`                                    |
| `init.image.tag`                                | Init container image tag                                            | `1.37.0`                                     |
| `init.image.pullPolicy`                         | Init container image pull policy                                    | `IfNotPresent`                               |
| `init.resourcesPreset`                          | Configure a preset for requests or limits for init container        | `nano`                                       |
| `init.resources`                                | Configure resource requests or limits for init container            | `{}`                                         |
| `init.securityContext`                          | Security context for init container                                 | *see `values.yaml`*                          |
| `test.image.registry`                           | Test container image registry                                       | `ghcr.io`                                    |
| `test.image.repository`                         | Test container image repository                                     | `busybox`                                    |
| `test.image.tag`                                | Test container image tag                                            | `1.37.0`                                     |
| `test.image.pullPolicy`                         | Test container image pull policy                                    | `IfNotPresent`                               |
| `test.resourcesPreset`                          | Configure a preset for requests or limits for test container        | `nano`                                       |
| `test.resources`                                | Configure resource requests or limits for test container            | `{}`                                         |
| `test.securityContext`                          | Security context for test container                                 | *see `values.yaml`*                          |
| `autoscaling.enabled`                           | Whether to enable the HorizontalPodAutoscaler                       | `false`                                      |
| `autoscaling.minReplicas`                       | Minimum number of replicas when autoscaling is enabled              | `1`                                          |
| `autoscaling.maxReplicas`                       | Maximum number of replicas when autoscaling is enabled              | `100`                                        |
| `autoscaling.targetCPUUtilizationPercentage`    | Target CPU utilisation percentage for autoscaling                   | `80`                                         |
| `autoscaling.targetMemoryUtilizationPercentage` | Target memory utilisation percentage for autoscaling                | `null`                                       |
| `autoscaling.behavior`                          | HPA behavior (scaleUp/scaleDown policies and settings)              | `{}`                                         |
| `nodeSelector`                                  | Node labels for pod assignment                                      | `{}`                                         |
| `tolerations`                                   | Toleration labels for pod assignment                                | `[]`                                         |
| `updateStrategy`                                | Configure deployment update strategy                                | `{}` (defaults to `RollingUpdate`)           |
| `affinity`                                      | Affinity settings for pod assignment                                | `{}`                                         |
| `extraEnvs`                                     | Additional environment variables to set in the NetBox container     | `[]`                                         |
| `extraVolumeMounts`                             | Additional volumes to mount in the NetBox container                 | `[]`                                         |
| `extraVolumes`                                  | Additional volumes to reference in pods                             | `[]`                                         |
| `sidecars`                                      | Additional sidecar containers to be added to pods                   | `[]`                                         |
| `initContainers`                                | Additional init containers to run before starting main containers   | `[]`                                         |
| `command`                                       | NetBox container custom command/entrypoint                          | `[]`                                         |
| `args`                                          | NetBox container custom args                                        | `[]`                                         |
| `worker`                                        | Worker specific variables. Most global variables also apply here.   | *see `values.yaml`*                          |
| `housekeeping.enabled`                          | Whether the [Housekeeping][housekeeping] `CronJob` should be active | `true`                                       |
| `housekeeping.concurrencyPolicy`                | ConcurrencyPolicy for the Housekeeping CronJob.                     | `Forbid`                                     |
| `housekeeping.failedJobsHistoryLimit`           | Number of failed jobs to keep in history                            | `5`                                          |
| `housekeeping.command`                          | The shell command to execute in the housekeeping job.               | `[/opt/netbox/venv/bin/python, /opt/netbox/netbox/manage.py, housekeeping]`|
| `housekeeping.args`                             | NetBox housekeeping container custom args                           | `[]`                                         |
| `housekeeping.restartPolicy`                    | Restart Policy for the Housekeeping CronJob.                        | `OnFailure`                                  |
| `housekeeping.schedule`                         | Schedule for the CronJob in [Cron syntax][cron syntax].             | `0 0 * * *` (Midnight daily)                 |
| `housekeeping.successfulJobsHistoryLimit`       | Number of successful jobs to keep in history                        | `5`                                          |
| `housekeeping.suspend`                          | Whether to suspend the CronJob                                      | `false`                                      |
| `housekeeping.podAnnotations`                   | Additional annotations for housekeeping CronJob pods                | `{}`                                         |
| `housekeeping.podLabels`                        | Additional labels for housekeeping CronJob pods                     | `{}`                                         |
| `housekeeping.podSecurityContext`               | Security context for housekeeping CronJob pods                      | *see `values.yaml`*                          |
| `housekeeping.securityContext`                  | Security context for housekeeping CronJob containers                | *see `values.yaml`*                          |
| `housekeeping.automountServiceAccountToken`     | Whether to automatically mount the serviceAccount token in the housekeeping container or not | `false`             |
| `housekeeping.resources`                        | Configure resource requests or limits for housekeeping CronJob      | `{}`                                         |
| `housekeeping.nodeSelector`                     | Node labels for housekeeping CronJob pod assignment                 | `{}`                                         |
| `housekeeping.tolerations`                      | Toleration labels for housekeeping CronJob pod assignment           | `[]`                                         |
| `housekeeping.affinity`                         | Affinity settings for housekeeping CronJob pod assignment           | `{}`                                         |
| `housekeeping.extraEnvs`                        | Additional environment variables to set in housekeeping CronJob     | `[]`                                         |
| `housekeeping.extraVolumeMounts`                | Additional volumes to mount in the housekeeping CronJob             | `[]`                                         |
| `housekeeping.extraVolumes`                     | Additional volumes to reference in housekeeping CronJob pods        | `[]`                                         |
| `housekeeping.sidecars`                         | Additional sidecar containers to be added to housekeeping CronJob   | `[]`                                         |
| `housekeeping.initContainers`                   | Additional init containers for housekeeping CronJob pods            | `[]`                                         |

<!-- prettier-ignore-end -->

[CORS]: https://github.com/ottoyiu/django-cors-headers
[housekeeping]: https://netboxlabs.com/docs/netbox/en/stable/administration/housekeeping/
[cron syntax]: https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax

Specify each parameter using the `--set key=value[,key=value]` argument to `helm install` or provide a YAML file containing the values for the above parameters:

```shell
helm install my-release --devel --values values.yaml \
  oci://ghcr.io/netbox-community/netbox-chart/netbox
```

## Persistent storage pitfalls

Persistent storage for media is enabled by default, but unless you take special
care you will run into issues. The most common issue is that one of the NetBox
pods gets stuck in the `ContainerCreating` state. There are several ways around
this problem:

<!-- prettier-ignore-start -->

1. Use the recommended S3 `storages` and **disable** persistent storage
    by setting `persistence.enabled` to `false`. This can
    be used with any S3-compatible storage provider including Amazon S3, Minio,
    Ceph RGW, and many others. See further down for an example of this.
2. Use a `ReadWriteMany` volume that can be mounted by several pods across
    nodes simultaneously.
3. Configure pod affinity settings to keep all the pods on the same node. This
    allows a `ReadWriteOnce` volume to be mounted in several pods at the same
    time.
4. Disable persistent storage of media altogether and just manage without. The
    storage functionality is only needed to store uploaded image attachments.

<!-- prettier-ignore-end -->

To configure the pod affinity to allow using a `ReadWriteOnce` volume you can
use the following example configuration:

```yaml
affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchLabels:
            app.kubernetes.io/name: netbox
        topologyKey: kubernetes.io/hostname

housekeeping:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app.kubernetes.io/name: netbox
          topologyKey: kubernetes.io/hostname

worker:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app.kubernetes.io/name: netbox
          topologyKey: kubernetes.io/hostname
```

## Using an Existing Secret

Rather than specifying passwords and secrets as part of the Helm release values,
you may pass these to NetBox using pre-existing `Secret` resources. When using
this, the respective `Secret`s must contain the following keys.

### Superuser secret (`superuser.existingSecret`)

Type: `kubernetes.io/basic-auth`

| Key         | Description                                          | Required? |
| ----------- | ---------------------------------------------------- | --------- |
| `username`  | Username for the initial super-user account          | Yes       |
| `password`  | Password for the initial super-user account          | Yes       |
| `email`     | Email address for the initial super-user account     | Yes       |
| `api_token` | API token created for the initial super-user account | Yes       |

### Config secret (`existingSecret`)

| Key                  | Description                                                   | Required?                                                                                         |
| -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `ldap_bind_password` | Password for LDAP bind DN                                     | If `remoteAuth.enabled` is `true` and `remoteAuth.backend` is `netbox.authentication.LDAPBackend` |
| `secret_key`         | Django secret key used for sessions and password reset tokens | Yes                                                                                               |

### Email secret (`email.existingSecretName`)

| Key                  | Description                                                   | Required?                                                                                         |
| -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `email-password`     | SMTP user password                                            | Yes, but the value may be left blank if not required                                              |

### PostgreSQL secret (`externalDatabase.existingSecretName`)

| Key                   | Description                                       | Required?                          |
| --------------------- | ------------------------------------------------- | ---------------------------------- |
| `postgresql-password` | The password for the external PostgreSQL database | If `postgresql.enabled` is `false` |

### Tasks secrets (`tasksDatabase.existingSecretName`)

| Key              | Description                                                   | Required?                     |
| ---------------- | ------------------------------------------------------------- | ----------------------------- |
| `tasks-password` | Password for the external KV database (tasks and/or cache)    | If `valkey.enabled` is `false` |

### Cache secrets (`cachingDatabase.existingSecretName`)

| Key              | Description                                                   | Required?                     |
| ---------------- | ------------------------------------------------------------- | ----------------------------- |
| `cache-password` | Password for the external KV database (tasks and/or cache)    | If `valkey.enabled` is `false` |

## License

This project is licensed under [Apache License, Version 2.0](LICENSE).


================================================
FILE: charts/netbox/ci/default-values.yaml
================================================


================================================
FILE: charts/netbox/ci/ingress-metrics-values.yaml
================================================
ingress:
  enabled: true

metrics:
  enabled: true


================================================
FILE: charts/netbox/ci/ldap-values.yaml
================================================
remoteAuth:
  enabled: true
  backends:
    - netbox.authentication.LDAPBackend

  ldap:
    serverUri: "ldap://ldap.forumsys.com"
    startTls: true
    ignoreCertErrors: true
    caCertData: ""
    bindDn: "cn=read-only-admin,dc=example,dc=com"
    bindPassword: password
    userDnTemplate: ""
    userSearchBaseDn: "dc=example,dc=com"
    userSearchAttr: "sAMAccountName"
    groupSearchBaseDn: "dc=example,dc=com"
    groupSearchClass: "group"
    groupType: "GroupOfNamesType"
    requireGroupDn:
      - "cn=read-only-admin,dc=example,dc=com"
    findGroupPerms: true
    mirrorGroups: true
    mirrorGroupsExcept: ""
    cacheTimeout: 3600
    isAdminDn:
      - "ou=mathematicians,cn=read-only-admin,dc=example,dc=com"
    isSuperUserDn:
      - "ou=scientists,cn=read-only-admin,dc=example,dc=com"
    attrFirstName: "givenName"
    attrLastName: "sn"
    attrMail: "mail"


================================================
FILE: charts/netbox/docs/auth.md
================================================
# Authentication Options

## Using SSO

You can configure different SSO backends with `remoteAuth`.
The implementation is based on [Python Social Auth](https://python-social-auth.readthedocs.io/en/latest/backends/index.html#supported-backends).

Depending on the chosen backend you may need to configure different parameters.
You can leverage the `extraConfig` value in conjunction with `remoteAuth`.

> [!tip]
> Read more about `extraConfig` usage within [Extra Configuration](./extra.md) guide.

By default the users do not have any permission after logging in.
Using custom auth pipelines you can assign groups based on the roles supplied by the oauth provider.

### Example config for Keycloak backend

```yaml
remoteAuth:
  enabled: true
  backends:
    - social_core.backends.keycloak.KeycloakOAuth2
  autoCreateUser: true

extraConfig:
  - secret:
      secretName: keycloak-client
  - values:
      SOCIAL_AUTH_PIPELINE:
        [
          "social_core.pipeline.social_auth.social_details",
          "social_core.pipeline.social_auth.social_uid",
          "social_core.pipeline.social_auth.social_user",
          "social_core.pipeline.user.get_username",
          "social_core.pipeline.social_auth.associate_by_email",
          "social_core.pipeline.user.create_user",
          "social_core.pipeline.social_auth.associate_user",
          "netbox.authentication.user_default_groups_handler",
          "social_core.pipeline.social_auth.load_extra_data",
          "social_core.pipeline.user.user_details",
          "netbox.sso_pipeline_roles.set_role",
        ]

extraVolumes:
  - name: sso-pipeline-roles
    configMap:
      name: sso-pipeline-roles
extraVolumeMounts:
  - name: sso-pipeline-roles
    mountPath: /opt/netbox/netbox/netbox/sso_pipeline_roles.py
    subPath: sso_pipeline_roles.py
    readOnly: true
```

Additional resources are necessary:

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: keycloak-client
  namespace: netbox
type: Opaque
data:
  oidc-keycloak.yaml: |
    SOCIAL_AUTH_KEYCLOAK_KEY:               <OAUTH_CLIENT_ID>
    SOCIAL_AUTH_KEYCLOAK_SECRET:            <OAUTH_CLIENT_SECRET>
    SOCIAL_AUTH_KEYCLOAK_PUBLIC_KEY:        MIIB...AB
    SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL: "https://keycloak.example.com/auth/realms/master/protocol/openid-connect/auth"
    SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL:  "https://keycloak.example.com/auth/realms/master/protocol/openid-connect/token"
    SOCIAL_AUTH_JSONFIELD_ENABLED:          true
    SOCIAL_AUTH_STAFF_ROLE:                 staff
    SOCIAL_AUTH_SUPERUSER_ROLE:             superuser

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: sso-pipeline-roles
  namespace: netbox
data:
  sso_pipeline_roles.py: |
    from django.conf import settings
    from netbox.authentication import Group

    def set_role(response, user, backend, *args, **kwargs):
      client_id = getattr(settings, 'SOCIAL_AUTH_KEYCLOAK_KEY', None)
      staff_role = getattr(settings, 'SOCIAL_AUTH_STAFF_ROLE', 'staff')
      superuser_role = getattr(settings, 'SOCIAL_AUTH_SUPERUSER_ROLE', 'superuser')

      roles = []
      try:
        roles = response['resource_access'][client_id]['roles']
      except KeyError:
        pass
      user.is_staff = (staff_role in roles)
      user.is_superuser = (superuser_role in roles)
      user.save()
      groups = Group.objects.all()
      for group in groups:
        try:
          if group.name in roles:
            group.users.add(user)
          else:
            group.users.remove(user)
        except Group.DoesNotExist:
          continue
```

> [!note]
> A hardcoded custom audience mapper is required on Keycloak.
>
> For the audience name to be in the token, enter the Client ID
> in the _Included **Custom** Audience_ field instead of the _Included **Client** Audience_ field.
>
> Refer to the Keycloak usage materials:
>
> - [Python Social Auth Documentation](https://python-social-auth.readthedocs.io/en/latest/backends/keycloak.html)
> - [Python Social Auth Source Code](https://github.com/python-social-auth/social-core/blob/d9554fa40e751c85ae60231fe2f5bd5a528c4452/social_core/backends/keycloak.py#L7-L96)
> - [Keycloak Documentation](https://www.keycloak.org/docs/latest/server_admin/#_audience_hardcoded)

### Example config for GitLab backend

```yaml
remoteAuth:
  enabled: true
  backends:
    - social_core.backends.gitlab.GitLabOAuth2
  autoCreateUser: true

extraConfig:
  - secret:
      secretName: gitlab-client
  - values:
      SOCIAL_AUTH_PIPELINE:
        [
            "social_core.pipeline.social_auth.social_details",
            "social_core.pipeline.social_auth.social_uid",
            "social_core.pipeline.social_auth.social_user",
            "social_core.pipeline.user.get_username",
            "social_core.pipeline.social_auth.associate_by_email",
            "social_core.pipeline.user.create_user",
            "social_core.pipeline.social_auth.associate_user",
            "netbox.authentication.user_default_groups_handler",
            "social_core.pipeline.social_auth.load_extra_data",
            "social_core.pipeline.user.user_details",
            "netbox.sso_pipeline_roles.set_role",
        ]
extraVolumes:
  - name: sso-pipeline-roles
    configMap:
      name: sso-pipeline-roles
extraVolumeMounts:
  - name: sso-pipeline-roles
    mountPath: /opt/netbox/netbox/netbox/sso_pipeline_roles.py
    subPath: sso_pipeline_roles.py
    readOnly: true
```

Additional resources are necessary (please note that the client ID is necessary in the custom pipeline script):

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: gitlab-client
  namespace: netbox
type: Opaque
stringData:
  oidc-gitlab.yaml: |
    SOCIAL_AUTH_GITLAB_API_URL: https://git.example.com
    SOCIAL_AUTH_GITLAB_AUTHORIZATION_URL: https://git.example.com/oauth/authorize
    SOCIAL_AUTH_GITLAB_ACCESS_TOKEN_URL: https://git.example.com/oauth/token
    SOCIAL_AUTH_GITLAB_KEY: <OAUTH_CLIENT_ID>
    SOCIAL_AUTH_GITLAB_SECRET: <OAUTH_CLIENT_SECRET>
    SOCIAL_AUTH_GITLAB_SCOPE: ['read_user', 'openid']
    SOCIAL_AUTH_STAFF_ROLE:                 staff
    SOCIAL_AUTH_SUPERUSER_ROLE:             superuser

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: sso-pipeline-roles
  namespace: netbox
data:
  sso_pipeline_roles.py: |
    from django.conf import settings
    from netbox.authentication import Group

    import jwt
    from jwt import PyJWKClient
    def set_role(response, user, backend, *args, **kwargs):
      client_id = getattr(settings, 'SOCIAL_AUTH_GITLAB_KEY', None)
      staff_role = getattr(settings, 'SOCIAL_AUTH_STAFF_ROLE', 'staff')
      superuser_role = getattr(settings, 'SOCIAL_AUTH_SUPERUSER_ROLE', 'superuser')

      jwks_client = PyJWKClient("https://git.example.com/oauth/discovery/keys")
      signing_key = jwks_client.get_signing_key_from_jwt(response['id_token'])
      decoded = jwt.decode(
          response['id_token'],
          signing_key.key,
          algorithms=["RS256"],
          audience=client_id,
      )
      roles = []
      try:
        roles = decoded.get('groups_direct')
      except KeyError:
        pass
      user.is_staff = (staff_role in roles)
      user.is_superuser = (superuser_role in roles)
      user.save()
      groups = Group.objects.all()
      for group in groups:
        try:
          if group.name in roles:
            group.users.add(user)
          else:
            group.users.remove(user)
        except Group.DoesNotExist:
          continue
```

## Using LDAP Authentication

In order to enable LDAP authentication, please carry out the following steps:

1. Configure the `remoteAuth` settings to enable the LDAP backend (see below)
2. Make sure you set _all_ of the `remoteAuth.ldap` settings shown in the `values.yaml` file

For example:

```yaml
remoteAuth:
  enabled: true
  backends:
    - netbox.authentication.LDAPBackend
  ldap:
    serverUri: ldap://domain.com
    startTls: true
    ignoreCertErrors: true
    bindDn: ""
    bindPassword: ""
    # and ALL the other remoteAuth.ldap.* settings from values.yaml
```

> [!NOTE]
> In order to use anonymous LDAP binding, set `bindDn` and `bindPassword`
> to an empty string as in the example above.

### LDAP Certificate Verification

If you need to specify your own CA certificate, follow the instructions below.

#### Option 1. In your `values.yaml` file define the directory already containing your CA certificate

```yaml
  ldap:
    serverUri: ldap://domain.com
    startTls: true
    ignoreCertErrors: false
    caCertDir: /etc/ssl/certs
```

#### Option 2. In your `values.yaml` file define your CA certificate content in `caCertData`

```yaml
  ldap:
    serverUri: ldap://domain.com
    startTls: true
    ignoreCertErrors: false
    caCertData: |
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
```


================================================
FILE: charts/netbox/docs/extra.md
================================================
# Extra Configuration

## Overview

Any additional configuration setting can be passed in the chart
values to be loaded into NetBox's instance.
They may be provided as arbitrary configuration values set, or
you can load arbitrary `*.yaml` keys from ConfigMaps and Secrets.

```yaml
extraConfig:
  - values:
      EXTRA_SETTING_ONE: example
      ANOTHER_SETTING: foobar
  - configMap: # pod.spec.volumes.configMap
      name: netbox-extra
      items: []
      optional: false
  - secret: # same as pod.spec.volumes.secret
      secretName: netbox-extra
      items: []
      optional: false
```

## NetBox Additional Configuration

For additional NetBox configuration setting, the recommended way is
to use the extra configuration value (`extraConfig`).

> [!note]
> In order to keep the chart's values reasonnable, only the
> [required](https://netboxlabs.com/docs/netbox/en/stable/configuration/required-parameters/)
> and critical configuration settings can be directly configured with a dedicated value field.

For example, the following snippet is configuring the value for
[`DEFAULT_DASHBOARD`](https://netboxlabs.com/docs/netbox/en/stable/configuration/default-values/#default_dashboard):

```yaml
extraConfig:
  - values:
      DEFAULT_DASHBOARD: 
        - widget: "extras.ObjectCountsWidget"
          width: 4
```

## ConfigMaps and Secrets Use

Any ConfigMaps and Secrets can be leveraged to provide configuration parameters.
The resource must provide the data under a `*.yaml` file description.

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: netbox-okta-credentials
  namespace: netbox
type: Opaque
stringData:
  okta.yaml: |
    SOCIAL_AUTH_OKTA_OPENIDCONNECT_KEY: ...
    SOCIAL_AUTH_OKTA_OPENIDCONNECT_SECRET: ...
    SOCIAL_AUTH_OKTA_OPENIDCONNECT_API_URL: ...
```

Then, it can be consumed using `extraConfig` using a the name as reference.

```yaml
extraConfig:
  - secret:
      secretName: netbox-okta-credentials
```

The variables will be retrieve by NetBox when loading.
In this example, the three variables (`SOCIAL_AUTH_OKTA_OPENIDCONNECT_*`)
will be available as global variables.

> [!tip]
> See more example of `extraConfig` within [Authentication Options](./auth.md) guide.


================================================
FILE: charts/netbox/docs/migrate.md
================================================
# Migration Guide

For major version updates (5.0.0, 6.0.0, etc.), see the release notes for detailed migration information.

## Back Up PostgreSQL

The first thing you should do is back up your PostgreSQL database.
This way you can always go back to your previous install version if anything goes wrong.

You can find your PostgreSQL pod by running `kubectl get pods -A | grep postgres` and then use `kubectl exec` to run `psql` or `pg_dump` from it.

## Upgrade PostgreSQL If Necessary

As of NetBox 3.6.x, NetBox requires PostgreSQL 12 or higher.
It is recommended that you upgrade to the latest supported PostgreSQL version.

If you are using the built-in PostgreSQL chart, you may need to update it separately, or update to the latest NetBox chart and dump your data back into it before NetBox will start.

## Upgrade NetBox

It is always recommended that you upgrade NetBox one major version at a time.
For example, if you are currently running NetBox 3.5.2 inside your chart, you would upgrade to the last 3.6.x version, then 3.7.x, and so on.

This ensures that migrations all run smoothly between versions.

## Check for Breaking Changes

Always look at the release notes for breaking changes.
There may be necessary changes to your `values.yaml` to ensure your configuration still works.


================================================
FILE: charts/netbox/docs/prod.md
================================================
# Production Considerations

## Database Recommendation

We recommend using separate external PostgreSQL and Key-Value instances. This
de-couples those services from the chart's bundled versions which may have
complex upgrade requirements. A clustered PostgreSQL server (e.g. using Zalando's
[Postgres Operator](https://github.com/zalando/postgres-operator)) and Redis
with Sentinel (e.g. using [Aaron Layfield](https://github.com/DandyDeveloper)'s
[redis-ha chart](https://github.com/DandyDeveloper/charts/tree/master/charts/redis-ha)).

## Storage Recommendation

Set `persistence.enabled` to `false` and use the S3 `storages`
for object storage. This works well with Minio or Ceph RGW as well as Amazon S3.
See [Persistent storage pitfalls](#persistent-storage-pitfalls), below.

Run multiple replicas of the NetBox web frontend to avoid interruptions during
upgrades or at other times when the pods need to be restarted. There's no need
to have multiple workers (`worker.replicaCount`) for better availability. Set
up `affinity.podAntiAffinity` to avoid multiple NetBox pods being colocated on
the same node, for example:

```yaml
affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchLabels:
            app.kubernetes.io/instance: netbox
            app.kubernetes.io/name: netbox
            app.kubernetes.io/component: netbox
        topologyKey: kubernetes.io/hostname
```

## Persistent Storage Pitfalls

Persistent storage for media is enabled by default, but unless you take special
care you will run into issues. The most common issue is that one of the NetBox
pods gets stuck in the `ContainerCreating` state. There are several ways around
this problem:

<!-- prettier-ignore-start -->

1. Use the recommended S3 `storageBackend` and **disable** persistent storage
    by setting `persistence.enabled` to `false`. This can
    be used with any S3-compatible storage provider including Amazon S3, Minio,
    Ceph RGW, and many others. See further down for an example of this.
2. Use a `ReadWriteMany` volume that can be mounted by several pods across
    nodes simultaneously.
3. Configure pod affinity settings to keep all the pods on the same node. This
    allows a `ReadWriteOnce` volume to be mounted in several pods at the same
    time.
4. Disable persistent storage of media altogether and just manage without. The
    storage functionality is only needed to store uploaded image attachments.

<!-- prettier-ignore-end -->

To configure the pod affinity to allow using a `ReadWriteOnce` volume you can
use the following example configuration:

```yaml
affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchLabels:
            app.kubernetes.io/name: netbox
        topologyKey: kubernetes.io/hostname

housekeeping:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app.kubernetes.io/name: netbox
          topologyKey: kubernetes.io/hostname

worker:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app.kubernetes.io/name: netbox
          topologyKey: kubernetes.io/hostname
```

## Disruption Budgets

To minimize downtime during voluntary disruptions (node drains, upgrades, autoscaling evictions), the chart can create PodDisruptionBudgets (PDBs) for both the web and worker Deployments.

- Configure web PDB via `pdb.*` values.
- Configure worker PDB via `worker.pdb.*` values.

Examples:

```yaml
# Ensure at least one web pod stays available at all times
pdb:
  enabled: true
  minAvailable: 1

# Allow one worker to be evicted at a time
worker:
  pdb:
    enabled: true
    maxUnavailable: 1
```


================================================
FILE: charts/netbox/files/configuration.py
================================================
"""
This file serves as a base configuration for Netbox
https://netboxlabs.com/docs/netbox/en/stable/configuration/
"""

import json
import os
import re
from pathlib import Path

import yaml


def _deep_merge(source, destination):
    """Inspired by https://stackoverflow.com/a/20666342"""
    for key, value in source.items():
        dst_value = destination.get(key)

        if isinstance(value, dict) and isinstance(dst_value, dict):
            _deep_merge(value, dst_value)
        else:
            destination[key] = value

    return destination


def _load_yaml() -> None:
    """Load YAML from files"""
    extra_config_base = Path("/run/config/extra")
    config_files = [Path("/run/config/netbox/netbox.yaml")]

    config_files.extend(sorted(extra_config_base.glob("*/*.yaml")))

    for config_file in config_files:
        with open(config_file, "r", encoding="utf-8") as f:
            config = yaml.safe_load(f)
        _deep_merge(config, globals())


def _read_secret(secret_name: str, secret_key: str, default: str | None = None) -> str | None:
    """Read secret from file"""
    try:
        secret = open(
            f"/run/secrets/{secret_name}/{secret_key}",
            "r",
            encoding="utf-8",
        )
    except EnvironmentError:
        return default
    with secret:
        return secret.read().strip()


CORS_ORIGIN_REGEX_WHITELIST = []
DATABASES = {}
EMAIL = {}
REDIS = {}

_load_yaml()

provided_secret_name = os.getenv("SECRET_NAME", "netbox")

DATABASES["default"]["PASSWORD"] = _read_secret(provided_secret_name, "db_password")
EMAIL["PASSWORD"] = _read_secret(provided_secret_name, "email_password")
REDIS["tasks"]["PASSWORD"] = _read_secret(provided_secret_name, "tasks_password")
REDIS["caching"]["PASSWORD"] = _read_secret(provided_secret_name, "cache_password")
SECRET_KEY = _read_secret(provided_secret_name, "secret_key")

# Read API token peppers from secret (JSON with integer or string keys)
_peppers_raw = _read_secret(provided_secret_name, "api_token_peppers")
if _peppers_raw:
    try:
        API_TOKEN_PEPPERS = {int(k): v for k, v in json.loads(_peppers_raw).items()}
    except (json.JSONDecodeError, ValueError, TypeError) as exc:
        raise ValueError(
            f"Invalid api_token_peppers secret: expected a JSON object mapping numeric "
            f'string keys to string values, e.g. {{"1": "random-string..."}}. '
            f"Keys are converted to integers at load time. Error: {exc}"
        ) from exc

# Post-process certain values
CORS_ORIGIN_REGEX_WHITELIST = [re.compile(r) for r in CORS_ORIGIN_REGEX_WHITELIST]
if "SENTINELS" in REDIS["tasks"]:
    REDIS["tasks"]["SENTINELS"] = [tuple(x.split(r":")) for x in REDIS["tasks"]["SENTINELS"]]
if "SENTINELS" in REDIS["caching"]:
    REDIS["caching"]["SENTINELS"] = [tuple(x.split(r":")) for x in REDIS["caching"]["SENTINELS"]]
if ALLOWED_HOSTS_INCLUDES_POD_ID:
    ALLOWED_HOSTS.append(os.getenv("POD_IP"))


================================================
FILE: charts/netbox/files/ldap_config.py
================================================
"""
This file serves as a LDAP configuration for Netbox
https://netboxlabs.com/docs/netbox/en/stable/installation/6-ldap/#configuration
https://django-auth-ldap.readthedocs.io/en/latest/reference.html
"""

from functools import reduce
from importlib import import_module
from typing import Any

import ldap
import yaml
from django_auth_ldap.config import LDAPGroupQuery, LDAPSearch


def _load_yaml() -> None:
    """Load YAML from file"""
    with open("/run/config/netbox/ldap.yaml", "r", encoding="utf-8") as f:
        config = yaml.safe_load(f)
    globals().update(config)


def _read_secret(secret_name: str, secret_key: str, default: str | None = None) -> str | None:
    """Read secret from file"""
    try:
        secret = open(
            f"/run/secrets/{secret_name}/{secret_key}",
            "r",
            encoding="utf-8",
        )
    except EnvironmentError:
        return default
    with secret:
        return secret.readline().strip()


def _import_group_type(group_type_name: str) -> Any | None:
    """Import and return the group type based on name"""
    mod = import_module("django_auth_ldap.config")
    try:
        return getattr(mod, group_type_name)()
    except AttributeError:
        return None


AUTH_LDAP_USER_SEARCH_FILTER = None
AUTH_LDAP_GROUP_SEARCH_FILTER = None
AUTH_LDAP_REQUIRE_GROUP = None
AUTH_LDAP_USER_FLAGS_BY_GROUP = {}

_load_yaml()

# The following may be needed if you are binding to Active Directory.
AUTH_LDAP_CONNECTION_OPTIONS = {ldap.OPT_REFERRALS: 0}

# Set the DN and password for the NetBox service account if needed.
AUTH_LDAP_BIND_PASSWORD = _read_secret("netbox", "ldap_bind_password")

# This search ought to return all groups to which the user belongs.
# django_auth_ldap uses this to determine group
# heirarchy.
AUTH_LDAP_USER_SEARCH = LDAPSearch(
    AUTH_LDAP_USER_SEARCH_BASEDN,
    ldap.SCOPE_SUBTREE,
    AUTH_LDAP_USER_SEARCH_FILTER or f"({AUTH_LDAP_USER_SEARCH_ATTR}=%(user)s)",
)
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
    AUTH_LDAP_GROUP_SEARCH_BASEDN,
    ldap.SCOPE_SUBTREE,
    AUTH_LDAP_GROUP_SEARCH_FILTER or f"(objectClass={AUTH_LDAP_GROUP_SEARCH_CLASS})",
)
AUTH_LDAP_GROUP_TYPE = _import_group_type(AUTH_LDAP_GROUP_TYPE)

# Define a group required to login.
if AUTH_LDAP_REQUIRE_GROUP_LIST:
    AUTH_LDAP_REQUIRE_GROUP = reduce(
        lambda query, group: query | LDAPGroupQuery(group),
        AUTH_LDAP_REQUIRE_GROUP_LIST,
        LDAPGroupQuery(""),
    )

# Define special user types using groups. Exercise great caution when assigning superuser status.
if AUTH_LDAP_REQUIRE_GROUP is not None:
    AUTH_LDAP_USER_FLAGS_BY_GROUP = {
        "is_active": AUTH_LDAP_REQUIRE_GROUP,
        "is_staff": reduce(
            lambda query, group: query | LDAPGroupQuery(group),
            AUTH_LDAP_IS_ADMIN_LIST,
            LDAPGroupQuery(""),
        ),
        "is_superuser": reduce(
            lambda query, group: query | LDAPGroupQuery(group),
            AUTH_LDAP_IS_SUPERUSER_LIST,
            LDAPGroupQuery(""),
        ),
    }


================================================
FILE: charts/netbox/templates/NOTES.txt
================================================
CHART NAME: {{ .Chart.Name  }}
CHART VERSION: {{ .Chart.Version  }}
APP VERSION: {{ .Chart.AppVersion  }}

** Please be patient while the chart is being deployed **

Netbox can be accessed through the following DNS name from within the cluster:

    {{ include "common.names.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} (port {{ .Values.service.port }})

To access Netbox site from outside the cluster follow the steps below.

{{- if .Values.ingress.enabled }}

You have configured NetBox to use an ingress controller, exposing the following URL(s):

{{- range $host := .Values.ingress.hosts }}
  {{- range .paths }}
  - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
  {{- end }}
{{- end }}

{{- else if contains "NodePort" .Values.service.type }}

Get the application URL by running these commands:

  export NODE_PORT=$(kubectl get --namespace {{ include "common.names.namespace" . | quote }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "common.names.fullname" . }})
  export NODE_IP=$(kubectl get nodes --namespace {{ include "common.names.namespace" . | quote }} -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT

{{- else if contains "LoadBalancer" .Values.service.type }}

Get the application URL by running these commands:

  export SERVICE_IP=$(kubectl get svc --namespace {{ include "common.names.namespace" . | quote }} {{ include "common.names.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  echo http://$SERVICE_IP:{{ .Values.service.port }}

      NOTE: It may take a few minutes for the LoadBalancer IP to be available.
            You can watch the status of by running 'kubectl get --namespace {{ include "common.names.namespace" . | quote }} svc -w {{ include "common.names.fullname" . }}'

{{- else if contains "ClusterIP" .Values.service.type }}

Get the application URL by running these commands:

  export POD_NAME=$(kubectl get pods --namespace {{ include "common.names.namespace" . | quote }} -l "app.kubernetes.io/name={{ include "common.names.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:8080

{{- end }}

{{- include "netbox.validateValues" . }}
{{- include "common.warnings.rollingTag" .Values.image }}
{{- include "common.warnings.rollingTag" .Values.init.image }}
{{- include "common.warnings.resources" (dict "sections" (list "" "worker") "context" $) }}


================================================
FILE: charts/netbox/templates/_helpers.tpl
================================================
{{/* vim: set filetype=mustache: */}}

{{/*
Return the proper image name
*/}}
{{- define "netbox.image" -}}
{{- include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global "chart" .Chart) -}}
{{- end -}}

{{/*
Return the proper image name (for the init container image)
*/}}
{{- define "netbox.init.image" -}}
{{- include "common.images.image" (dict "imageRoot" .Values.init.image "global" .Values.global) -}}
{{- end -}}

{{/*
Create the name of the service account to use
*/}}
{{- define "netbox.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "common.names.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

{{/*
Name of the key in Secret that contains the email password
*/}}
{{- define "netbox.email.secretKey" -}}
  {{- if .Values.email.existingSecretName -}}
    {{- .Values.email.existingSecretKey -}}
  {{- else -}}
    email_password
  {{- end -}}
{{- end }}

{{/*
Name of the Secret that contains the PostgreSQL password
*/}}
{{- define "netbox.postgresql.secret" -}}
  {{- if .Values.postgresql.enabled }}
    {{- include "postgresql.v1.secretName" .Subcharts.postgresql -}}
  {{- else }}
    {{- include "common.secrets.name" (dict "existingSecret" .Values.externalDatabase.existingSecretName "defaultNameSuffix" "postgresql" "context" $) }}
  {{- end }}
{{- end }}

{{/*
Name of the key in Secret that contains the PostgreSQL password
*/}}
{{- define "netbox.postgresql.secretKey" -}}
  {{- if .Values.postgresql.enabled -}}
    {{- include "postgresql.v1.userPasswordKey" .Subcharts.postgresql -}}
  {{- else if .Values.externalDatabase.existingSecretName -}}
    {{- .Values.externalDatabase.existingSecretKey -}}
  {{- else -}}
    db_password
  {{- end -}}
{{- end }}

{{/*
Name of the Secret that contains the Valkey tasks password
*/}}
{{- define "netbox.tasksDatabase.secret" -}}
  {{- if .Values.valkey.enabled }}
    {{- include "valkey.secretName" .Subcharts.valkey -}}
  {{- else }}
    {{- include "common.secrets.name" (dict "existingSecret" .Values.tasksDatabase.existingSecretName "defaultNameSuffix" "kv" "context" $) }}
  {{- end }}
{{- end }}

{{/*
Name of the key in Secret that contains the Valkey tasks password
*/}}
{{- define "netbox.tasksDatabase.secretKey" -}}
  {{- if .Values.valkey.enabled -}}
    {{- include "valkey.secretPasswordKey" .Subcharts.valkey -}}
  {{- else if .Values.tasksDatabase.existingSecretName -}}
    {{ .Values.tasksDatabase.existingSecretKey }}
  {{- else -}}
    tasks_password
  {{- end -}}
{{- end }}

{{/*
Name of the Secret that contains the Valkey cache password
*/}}
{{- define "netbox.cachingDatabase.secret" -}}
  {{- if .Values.valkey.enabled }}
    {{- include "valkey.secretName" .Subcharts.valkey -}}
  {{- else }}
    {{- include "common.secrets.name" (dict "existingSecret" .Values.cachingDatabase.existingSecretName "defaultNameSuffix" "kv" "context" $) }}
  {{- end }}
{{- end }}

{{/*
Name of the key in Secret that contains the Valkey cache password
*/}}
{{- define "netbox.cachingDatabase.secretKey" -}}
  {{- if .Values.valkey.enabled -}}
    {{- include "valkey.secretPasswordKey" .Subcharts.valkey -}}
  {{- else if .Values.cachingDatabase.existingSecretName -}}
    {{ .Values.cachingDatabase.existingSecretKey }}
  {{- else -}}
    cache_password
  {{- end -}}
{{- end }}

{{/*
Valkey Sentinels that would result from setting .Values.valkey.enabled=true and .Values.valkey.sentinel.enabled=true
*/}}
{{- define "netbox.valkey.managedSentinels" -}}
  {{- $sentinels := list }}
  {{- $fullname := include "common.names.fullname" .Subcharts.valkey }}
  {{- $headlessService := printf "%s-headless" (include "common.names.fullname" .Subcharts.valkey) }}
  {{- $sentinelPort := toString .Values.valkey.sentinel.service.ports.sentinel }}
  {{- range $i := until (int .Values.valkey.replica.replicaCount) }}
    {{- $sentinels = append $sentinels (printf "%s-node-%s.%s:%s" $fullname (toString $i) $headlessService $sentinelPort) }}
  {{- end }}
  {{- toJson $sentinels }}
{{- end -}}

{{/*
Tasks Sentinel: use .Values.tasksDatabase.sentinels if defined. When using embedded Valkey Sentinel feature, fallback to generated sentinels
*/}}
{{- define "netbox.tasksDatabase.sentinels" -}}
  {{- if .Values.tasksDatabase.sentinels }}
    {{- toJson .Values.tasksDatabase.sentinels }}
  {{- else if and .Values.valkey.enabled .Values.valkey.sentinel.enabled }}
    {{- include "netbox.valkey.managedSentinels" . }}
  {{- end }}
{{- end -}}

{{/*
Caching Sentinel: use .Values.cachingDatabase.sentinels if defined. When using embedded Valkey Sentinel feature, fallback to generated sentinels
*/}}
{{- define "netbox.cachingDatabase.sentinels" -}}
  {{- if .Values.cachingDatabase.sentinels }}
    {{- toJson .Values.cachingDatabase.sentinels }}
  {{- else if and .Values.valkey.enabled .Values.valkey.sentinel.enabled }}
    {{- include "netbox.valkey.managedSentinels" . }}
  {{- end }}
{{- end -}}

{{/*
Volumes that need to be mounted for .Values.extraConfig entries
*/}}
{{- define "netbox.extraConfig.volumes" -}}
{{- range $index, $config := .Values.extraConfig }}
- name: {{ printf "extra-config-%d" $index | quote }}
  {{- if $config.values }}
  configMap:
    name: {{ include "common.names.fullname" $ }}
    items:
    - key: {{ printf "extra-%d.yaml" $index | quote }}
      path: {{ printf "extra-%d.yaml" $index | quote }}
  {{- else if $config.configMap }}
  configMap:
    {{- include "common.tplvalues.render" (dict "value" $config.configMap "context" $) | nindent 4 }}
  {{- else if $config.secret }}
  secret:
    {{- include "common.tplvalues.render" (dict "value" $config.secret "context" $) | nindent 4 }}
  {{- end }}
{{- end }}
{{- end }}

{{/*
Volume mounts for .Values.extraConfig entries
*/}}
{{- define "netbox.extraConfig.volumeMounts" -}}
{{- range $index, $config := .Values.extraConfig }}
- name: {{ printf "extra-config-%d" $index | quote }}
  mountPath: /run/config/extra/{{ $index }}
  readOnly: true
{{- end }}
{{- end }}

{{/*
Generate the api_token_peppers secret value.
Returns a base64-encoded, quoted JSON object.

Priority:
  1. User-provided apiTokenPeppers from values.yaml (always wins for rotation)
  2. Existing secret value (preserved across upgrades via lookup)
  3. Auto-generated single pepper {"1": "<random 50 chars>"}
*/}}
{{- define "netbox.apiTokenPeppers.secret" -}}
{{- if not (empty .Values.apiTokenPeppers) -}}
  {{- .Values.apiTokenPeppers | toJson | b64enc | quote }}
{{- else -}}
  {{- $secretName := include "common.secrets.name" (dict "defaultNameSuffix" "config" "context" $) -}}
  {{- $existingSecret := (lookup "v1" "Secret" (include "common.names.namespace" .) $secretName).data -}}
  {{- if and $existingSecret (hasKey $existingSecret "api_token_peppers") -}}
    {{- index $existingSecret "api_token_peppers" | quote }}
  {{- else -}}
    {{- $pepper := randAlphaNum 50 -}}
    {{- dict "1" $pepper | toJson | b64enc | quote }}
  {{- end -}}
{{- end -}}
{{- end -}}

{{/*
Compile all warnings into a single message.
*/}}
{{- define "netbox.validateValues" -}}
{{- $messages := list -}}
{{- $messages := append $messages (include "netbox.validateValues.postgresql" .) -}}
{{- $messages := append $messages (include "netbox.validateValues.ldap" .) -}}
{{- $messages := without $messages "" -}}
{{- $message := join "\n" $messages -}}
{{- if $message -}}
{{-   printf "\nVALUES VALIDATION:\n%s" $message | fail -}}
{{- end -}}
{{- end -}}

{{/*
Validate values of Netbox Chart - PostgreSQL
*/}}
{{- define "netbox.validateValues.postgresql" -}}
{{- if and (not .Values.postgresql.enabled) (or (empty .Values.externalDatabase.host) (empty .Values.externalDatabase.port) (empty .Values.externalDatabase.database)) -}}
netbox: postgresql
    PostgreSQL installation has been disabled but without the required parameters
    to use an external database. To use an external database, please ensure you provide
    (at least) the following values:
        externalDatabase.host=DB_SERVER_HOST
        externalDatabase.database=DB_NAME
        externalDatabase.port=DB_SERVER_PORT
{{- end -}}
{{- end -}}

{{/*
Validate values of Netbox Chart - LDAP
*/}}
{{- define "netbox.validateValues.ldap" -}}
{{- if and (has "netbox.authentication.LDAPBackend" .Values.remoteAuth.backends) (empty .Values.remoteAuth.ldap.serverUri) -}}
netbox: remoteAuth.ldap
    When LDAP backend is activated, you must provide all the necessary parameters.
    Review the values under `remoteAuth.ldap`.
{{- end -}}
{{- end -}}


================================================
FILE: charts/netbox/templates/configmap.yaml
================================================
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "common.names.fullname" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
data:
  configuration.py: |-
    {{ .Files.Get "files/configuration.py" | nindent 4 }}

  netbox.yaml: |-
    ALLOWED_HOSTS: {{ toJson .Values.allowedHosts }}
    ALLOWED_HOSTS_INCLUDES_POD_ID: {{ .Values.allowedHostsIncludesPodIP }}

    DATABASES:
      default:
        {{- if .Values.postgresql.enabled }}
        HOST: {{ include "postgresql.v1.primary.fullname" .Subcharts.postgresql | quote }}
        USER: {{ include "postgresql.v1.username" .Subcharts.postgresql | quote }}
        NAME: {{ include "postgresql.v1.database" .Subcharts.postgresql | quote }}
        PORT: {{ include "postgresql.v1.service.port" .Subcharts.postgresql | int }}
        {{- else }}
        HOST: {{ include "common.tplvalues.render" (dict "value" .Values.externalDatabase.host "context" $) | quote }}
        USER: {{ include "common.tplvalues.render" (dict "value" .Values.externalDatabase.username "context" $) | quote }}
        NAME: {{ include "common.tplvalues.render" (dict "value" .Values.externalDatabase.database "context" $) | quote }}
        PORT: {{ include "common.tplvalues.render" (dict "value" .Values.externalDatabase.port "context" $) | int }}
        {{- end }}
        ENGINE: {{ .Values.externalDatabase.engine | quote }}
        OPTIONS: {{- include "common.tplvalues.render" (dict "value" .Values.externalDatabase.options "context" $) | nindent 10 }}
        CONN_MAX_AGE: {{ .Values.externalDatabase.connMaxAge | int }}
        DISABLE_SERVER_SIDE_CURSORS: {{ toJson .Values.externalDatabase.disableServerSideCursors }}
      {{- range $key, $db := .Values.additionalDatabases }}
      {{ $key }}:
        ENGINE: {{ $db.engine | quote }}
        NAME: {{ $db.database | quote }}
        USER: {{ $db.username | quote }}
        HOST: {{ $db.host | quote }}
        PORT: {{ $db.port | int }}
        CONN_MAX_AGE: {{ $db.connMaxAge | int }}
        OPTIONS: {{- include "common.tplvalues.render" (dict "value" $db.options "context" $) | nindent 10 }}
        DISABLE_SERVER_SIDE_CURSORS: {{ toJson $db.disableServerSideCursors }}
      {{- end }}

    ADMINS: {{ toJson .Values.admins }}
    ALLOW_TOKEN_RETRIEVAL: {{ toJson .Values.allowTokenRetrieval }}
    AUTH_PASSWORD_VALIDATORS: {{ toJson .Values.authPasswordValidators }}
    ALLOWED_URL_SCHEMES: {{ toJson .Values.allowedUrlSchemes }}
    {{- range $k, $v := .Values.banner }}
    BANNER_{{ upper $k }}: {{ $v | quote }}
    {{- end }}
    BASE_PATH: {{ .Values.basePath | quote }}
    CHANGELOG_RETENTION: {{ int .Values.changelogRetention }}
    CUSTOM_VALIDATORS: {{ toJson .Values.customValidators }}
    DEFAULT_USER_PREFERENCES: {{ toJson .Values.defaultUserPreferences }}
    CORS_ORIGIN_ALLOW_ALL: {{ toJson .Values.cors.originAllowAll }}
    CORS_ORIGIN_WHITELIST: {{ toJson .Values.cors.originWhitelist }}
    CORS_ORIGIN_REGEX_WHITELIST: {{ toJson .Values.cors.originRegexWhitelist }}
    CSRF_TRUSTED_ORIGINS: {{ toJson .Values.csrf.trustedOrigins }}
    DATA_UPLOAD_MAX_MEMORY_SIZE: {{ int .Values.dataUploadMaxMemorySize }}
    DEBUG: {{ toJson .Values.debug }}
    DEFAULT_LANGUAGE: {{ .Values.defaultLanguage | quote }}

    EMAIL:
      SERVER: {{ .Values.email.server | quote }}
      PORT: {{ .Values.email.port | int }}
      USERNAME: {{ .Values.email.username | quote }}
      USE_SSL: {{ toJson .Values.email.useSSL }}
      USE_TLS: {{ toJson .Values.email.useTLS }}
      SSL_CERTFILE: {{ .Values.email.sslCertFile | quote }}
      SSL_KEYFILE: {{ .Values.email.sslKeyFile | quote }}
      TIMEOUT: {{ .Values.email.timeout | int }}
      FROM_EMAIL: {{ toJson .Values.email.from }}

    ENFORCE_GLOBAL_UNIQUE: {{ toJson .Values.enforceGlobalUnique }}
    EXEMPT_VIEW_PERMISSIONS: {{ toJson .Values.exemptViewPermissions }}
    FIELD_CHOICES: {{ toJson .Values.fieldChoices }}
    FILE_UPLOAD_MAX_MEMORY_SIZE: {{ int .Values.fileUploadMaxMemorySize }}
    GRAPHQL_ENABLED: {{ toJson .Values.graphQlEnabled }}
    HTTP_PROXIES: {{ toJson .Values.httpProxies }}
    INTERNAL_IPS: {{ toJson .Values.internalIPs }}
    JOB_RETENTION: {{ int .Values.jobRetention }}
    LOGGING: {{ toJson .Values.logging }}
    LOGIN_PERSISTENCE: {{ toJson .Values.loginPersistence }}
    LOGIN_REQUIRED: {{ toJson .Values.loginRequired }}
    LOGIN_TIMEOUT: {{ int .Values.loginTimeout }}
    LOGOUT_REDIRECT_URL: {{ .Values.logoutRedirectUrl | quote }}
    {{- if ne nil .Values.maintenanceMode }}
    MAINTENANCE_MODE: {{ toJson .Values.maintenanceMode }}
    {{- end }}
    MAPS_URL: {{ .Values.mapsUrl | quote }}
    MAX_PAGE_SIZE: {{ int .Values.maxPageSize }}
    MEDIA_ROOT: /opt/netbox/netbox/media
    STORAGES: {{ toJson .Values.storages }}
    METRICS_ENABLED: {{ toJson .Values.metrics.enabled }}
    PAGINATE_COUNT: {{ int .Values.paginateCount }}
    PLUGINS: {{ toJson .Values.plugins }}
    PLUGINS_CONFIG: {{ toJson .Values.pluginsConfig }}
    POWERFEED_DEFAULT_AMPERAGE: {{ int .Values.powerFeedDefaultAmperage }}
    POWERFEED_DEFAULT_MAX_UTILIZATION: {{ int .Values.powerFeedMaxUtilisation }}
    POWERFEED_DEFAULT_VOLTAGE: {{ int .Values.powerFeedDefaultVoltage }}
    PREFER_IPV4: {{ toJson .Values.preferIPv4 }}
    RACK_ELEVATION_DEFAULT_UNIT_HEIGHT: {{ int .Values.rackElevationDefaultUnitHeight }}
    RACK_ELEVATION_DEFAULT_UNIT_WIDTH: {{ int .Values.rackElevationDefaultUnitWidth }}
    REMOTE_AUTH_ENABLED: {{ toJson .Values.remoteAuth.enabled }}
    REMOTE_AUTH_BACKEND: {{ toJson .Values.remoteAuth.backends }}
    REMOTE_AUTH_HEADER: {{ .Values.remoteAuth.header | quote }}
    REMOTE_AUTH_USER_FIRST_NAME: {{ .Values.remoteAuth.userFirstName | quote }}
    REMOTE_AUTH_USER_LAST_NAME: {{ .Values.remoteAuth.userLastName | quote }}
    REMOTE_AUTH_USER_EMAIL: {{ .Values.remoteAuth.userEmail | quote }}
    REMOTE_AUTH_AUTO_CREATE_USER: {{ toJson .Values.remoteAuth.autoCreateUser }}
    REMOTE_AUTH_AUTO_CREATE_GROUPS: {{ toJson .Values.remoteAuth.autoCreateGroups }}
    REMOTE_AUTH_DEFAULT_GROUPS: {{ toJson .Values.remoteAuth.defaultGroups }}
    REMOTE_AUTH_DEFAULT_PERMISSIONS: {{ toJson .Values.remoteAuth.defaultPermissions }}
    REMOTE_AUTH_GROUP_SYNC_ENABLED: {{ toJson .Values.remoteAuth.groupSyncEnabled }}
    REMOTE_AUTH_GROUP_HEADER: {{ .Values.remoteAuth.groupHeader | quote }}
    REMOTE_AUTH_SUPERUSER_GROUPS: {{ toJson .Values.remoteAuth.superuserGroups }}
    REMOTE_AUTH_SUPERUSERS: {{ toJson .Values.remoteAuth.superusers }}
    REMOTE_AUTH_STAFF_GROUPS: {{ toJson .Values.remoteAuth.staffGroups }}
    REMOTE_AUTH_STAFF_USERS: {{ toJson .Values.remoteAuth.staffUsers }}
    REMOTE_AUTH_GROUP_SEPARATOR: {{ .Values.remoteAuth.groupSeparator | quote }}
    RELEASE_CHECK_URL: {{ toJson .Values.releaseCheck.url }}

    REDIS:
      tasks:
        {{- if (include "netbox.tasksDatabase.sentinels" .) }}
        SENTINELS: {{ include "netbox.tasksDatabase.sentinels" . }}
        SENTINEL_SERVICE: {{ ternary .Values.valkey.sentinel.primarySet .Values.tasksDatabase.sentinelService (empty .Values.tasksDatabase.sentinels) | quote }}
        SENTINEL_TIMEOUT: {{ .Values.tasksDatabase.sentinelTimeout | int }}
        {{- else if .Values.valkey.enabled }}
        HOST: {{ printf "%s-primary" (include "common.names.fullname" .Subcharts.valkey) | quote }}
        PORT: {{ .Values.valkey.primary.service.ports.valkey | int }}
        {{- else }}
        HOST: {{ .Values.tasksDatabase.host | quote }}
        PORT: {{ .Values.tasksDatabase.port | int }}
        {{- end }}
        USERNAME: {{ .Values.tasksDatabase.username | quote }}
        DATABASE: {{ int .Values.tasksDatabase.database }}
        SSL: {{ toJson .Values.tasksDatabase.ssl }}
        INSECURE_SKIP_TLS_VERIFY: {{ toJson .Values.tasksDatabase.insecureSkipTlsVerify }}
        CA_CERT_PATH: {{ .Values.tasksDatabase.caCertPath | quote }}
      caching:
        {{- if (include "netbox.cachingDatabase.sentinels" .) }}
        SENTINELS: {{ include "netbox.cachingDatabase.sentinels" . }}
        SENTINEL_SERVICE: {{ ternary .Values.valkey.sentinel.primarySet .Values.cachingDatabase.sentinelService (empty .Values.cachingDatabase.sentinels) | quote }}
        SENTINEL_TIMEOUT: {{ .Values.cachingDatabase.sentinelTimeout | int }}
        {{- else if .Values.valkey.enabled }}
        HOST: {{ printf "%s-primary" (include "common.names.fullname" .Subcharts.valkey) | quote }}
        PORT: {{ .Values.valkey.primary.service.ports.valkey | int }}
        {{- else }}
        HOST: {{ .Values.cachingDatabase.host | quote }}
        PORT: {{ .Values.cachingDatabase.port | int}}
        {{- end }}
        USERNAME: {{ .Values.cachingDatabase.username | quote }}
        DATABASE: {{ int .Values.cachingDatabase.database }}
        SSL: {{ toJson .Values.cachingDatabase.ssl }}
        INSECURE_SKIP_TLS_VERIFY: {{ toJson .Values.cachingDatabase.insecureSkipTlsVerify }}
        CA_CERT_PATH: {{ .Values.cachingDatabase.caCertPath | quote }}

    REPORTS_ROOT: /opt/netbox/netbox/reports
    RQ_DEFAULT_TIMEOUT: {{ .Values.rqDefaultTimeout | int }}
    SCRIPTS_ROOT: /opt/netbox/netbox/scripts
    CSRF_COOKIE_NAME: {{ .Values.csrf.cookieName | quote }}
    SESSION_COOKIE_NAME: {{ .Values.sessionCookieName }}
    ENABLE_LOCALIZATION: {{ toJson .Values.enableLocalization }}
    TIME_ZONE: {{ .Values.timeZone | quote }}
    DATE_FORMAT: {{ .Values.dateFormat | quote }}
    SHORT_DATE_FORMAT: {{ .Values.shortDateFormat | quote }}
    TIME_FORMAT: {{ .Values.timeFormat | quote }}
    SHORT_TIME_FORMAT: {{ .Values.shortTimeFormat | quote }}
    DATETIME_FORMAT: {{ .Values.dateTimeFormat | quote }}
    SHORT_DATETIME_FORMAT: {{ .Values.shortDateTimeFormat | quote }}

  {{- if has "netbox.authentication.LDAPBackend" .Values.remoteAuth.backends }}
  ldap_config.py: |-
    {{ .Files.Get "files/ldap_config.py" | nindent 4 }}

  ldap.yaml: |-
    AUTH_LDAP_SERVER_URI: {{ .Values.remoteAuth.ldap.serverUri | quote }}
    AUTH_LDAP_BIND_DN: {{ .Values.remoteAuth.ldap.bindDn | quote }}
    AUTH_LDAP_START_TLS: {{ toJson .Values.remoteAuth.ldap.startTls }}
    LDAP_IGNORE_CERT_ERRORS: {{ toJson .Values.remoteAuth.ldap.ignoreCertErrors }}
    {{- if .Values.remoteAuth.ldap.caCertDir }}
    LDAP_CA_CERT_DIR: {{ .Values.remoteAuth.ldap.caCertDir | quote }}
    {{- end }}
    {{- if .Values.remoteAuth.ldap.caCertData }}
    LDAP_CA_CERT_FILE: /etc/netbox/config/ldap/ldap_ca.crt
    {{- end }}
    AUTH_LDAP_USER_DN_TEMPLATE: {{ default nil .Values.remoteAuth.ldap.userDnTemplate }}
    AUTH_LDAP_USER_SEARCH_BASEDN: {{ .Values.remoteAuth.ldap.userSearchBaseDn | quote }}
    AUTH_LDAP_USER_SEARCH_ATTR: {{ .Values.remoteAuth.ldap.userSearchAttr | quote }}
    AUTH_LDAP_GROUP_SEARCH_BASEDN: {{ .Values.remoteAuth.ldap.groupSearchBaseDn | quote }}
    AUTH_LDAP_GROUP_SEARCH_CLASS: {{ .Values.remoteAuth.ldap.groupSearchClass | quote }}
    AUTH_LDAP_GROUP_TYPE: {{ .Values.remoteAuth.ldap.groupType | quote }}
    AUTH_LDAP_FIND_GROUP_PERMS: {{ toJson .Values.remoteAuth.ldap.findGroupPerms }}
    AUTH_LDAP_MIRROR_GROUPS: {{ toJson .Values.remoteAuth.ldap.mirrorGroups }}
    AUTH_LDAP_MIRROR_GROUPS_EXCEPT: {{ toJson .Values.remoteAuth.ldap.mirrorGroupsExcept }}
    AUTH_LDAP_CACHE_TIMEOUT: {{ int .Values.remoteAuth.ldap.cacheTimeout }}

    AUTH_LDAP_REQUIRE_GROUP_LIST: {{ toJson .Values.remoteAuth.ldap.requireGroupDn }}
    AUTH_LDAP_IS_ADMIN_LIST: {{ toJson .Values.remoteAuth.ldap.isAdminDn }}
    AUTH_LDAP_IS_SUPERUSER_LIST: {{ toJson .Values.remoteAuth.ldap.isSuperUserDn }}

    # Populate the Django user from the LDAP directory.
    AUTH_LDAP_USER_ATTR_MAP:
      first_name: {{ .Values.remoteAuth.ldap.attrFirstName | quote }}
      last_name: {{ .Values.remoteAuth.ldap.attrLastName | quote }}
      email: {{ .Values.remoteAuth.ldap.attrMail | quote }}

  {{- if .Values.remoteAuth.ldap.caCertData }}
  ldap_ca.crt: {{- toYaml .Values.remoteAuth.ldap.caCertData | indent 4 }}
  {{- end }}
  {{- end }}

  {{- range $index, $config := .Values.extraConfig }}
  {{- if $config.values }}
  {{ printf "extra-%d.yaml" $index }}: |-
    {{- include "common.tplvalues.render" (dict "value" $config.values "context" $) | nindent 4 }}
  {{- end }}
  {{- end }}


================================================
FILE: charts/netbox/templates/cronjob.yaml
================================================
{{- if .Values.housekeeping.enabled -}}
apiVersion: batch/v1
kind: CronJob
metadata:
  name: {{ printf "%s-housekeeping" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
    app.kubernetes.io/component: housekeeping
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
spec:
  concurrencyPolicy: {{ .Values.housekeeping.concurrencyPolicy }}
  failedJobsHistoryLimit: {{ .Values.housekeeping.failedJobsHistoryLimit }}
  schedule: {{ .Values.housekeeping.schedule | quote }}
  successfulJobsHistoryLimit: {{ .Values.housekeeping.successfulJobsHistoryLimit }}
  suspend: {{ .Values.housekeeping.suspend }}
  {{- if .Values.housekeeping.timezone }}
  timeZone: {{ .Values.housekeeping.timezone }}
  {{- end }}
  jobTemplate:
    metadata:
      labels:
        {{- include "common.labels.standard" . | nindent 8 }}
    spec:
      template:
        metadata:
          {{- if .Values.housekeeping.podAnnotations }}
          annotations:
            {{- include "common.tplvalues.render" ( dict "value" .Values.housekeeping.podAnnotations "context" $ ) | nindent 12 }}
          {{- end }}
          labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.housekeeping.podLabels "context" $ ) | nindent 12 }}
            app.kubernetes.io/component: housekeeping
        spec:
          {{- include "common.images.renderPullSecrets" (dict "images" (list .Values.image) "context" $) | nindent 10 }}
          serviceAccountName: {{ include "netbox.serviceAccountName" . }}
          automountServiceAccountToken: {{ .Values.housekeeping.automountServiceAccountToken }}
          {{- if .Values.housekeeping.podSecurityContext.enabled }}
          securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.housekeeping.podSecurityContext "context" $) | nindent 12 }}
          {{- end }}
          {{- if .Values.housekeeping.initContainers }}
          initContainers: {{- include "common.tplvalues.render" (dict "value" .Values.housekeeping.initContainers "context" $) | trim | nindent 12 }}
          {{- end }}
          containers:
          - name: {{ .Chart.Name }}-housekeeping
            {{- if .Values.housekeeping.securityContext.enabled }}
            securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.housekeeping.securityContext "context" $) | nindent 14 }}
            {{- end }}
            image: {{ include "netbox.image" . | quote }}
            imagePullPolicy: {{ .Values.image.pullPolicy }}
            {{- if .Values.housekeeping.command }}
            command: {{- include "common.tplvalues.render" (dict "value" .Values.housekeeping.command "context" $) | nindent 14 }}
            {{- end }}
            {{- if .Values.housekeeping.args }}
            args: {{- include "common.tplvalues.render" (dict "value" .Values.housekeeping.args "context" $) | nindent 14 }}
            {{- end }}
            {{- if .Values.housekeeping.extraEnvs }}
            env: {{- include "common.tplvalues.render" (dict "value" .Values.housekeeping.extraEnvs "context" $) | nindent 14 }}
            {{- end }}
            {{- if or .Values.housekeeping.extraEnvVarsCM .Values.housekeeping.extraEnvVarsSecret }}
            envFrom:
              {{- if .Values.housekeeping.extraEnvVarsCM }}
              - configMapRef:
                  name: {{ include "common.tplvalues.render" (dict "value" .Values.housekeeping.extraEnvVarsCM "context" $) }}
              {{- end }}
              {{- if .Values.housekeeping.extraEnvVarsSecret }}
              - secretRef:
                  name: {{ include "common.tplvalues.render" (dict "value" .Values.housekeeping.extraEnvVarsSecret "context" $) }}
              {{- end }}
            {{- end }}
            volumeMounts:
            - name: config
              mountPath: /etc/netbox/config/configuration.py
              subPath: configuration.py
              readOnly: true
            {{- if has "netbox.authentication.LDAPBackend" .Values.remoteAuth.backends }}
            - name: config
              mountPath: /etc/netbox/config/ldap/ldap_config.py
              subPath: ldap_config.py
              readOnly: true
            {{- if .Values.remoteAuth.ldap.caCertData }}
            - name: config
              mountPath: /etc/netbox/config/ldap/ldap_ca.crt
              subPath: ldap_ca.crt
              readOnly: true
            {{- end }}
            {{- end }}
            - name: config
              mountPath: /run/config/netbox
              readOnly: true
            - name: secrets
              mountPath: /run/secrets/netbox
              readOnly: true
            {{- include "netbox.extraConfig.volumeMounts" . | nindent 12 }}
            - name: netbox-tmp
              mountPath: /tmp
            - name: media
              mountPath: /opt/netbox/netbox/media
              subPath: {{ .Values.persistence.subPath | default "" | quote }}
              readOnly: {{ .Values.housekeeping.readOnlyPersistence | default false }}
            {{- if .Values.reportsPersistence.enabled }}
            - name: reports
              mountPath: /opt/netbox/netbox/reports
              subPath: {{ .Values.reportsPersistence.subPath | default "" | quote }}
              readOnly: {{ .Values.housekeeping.readOnlyPersistence | default false }}
            {{- end }}
            {{- if .Values.scriptsPersistence.enabled }}
            - name: scripts
              mountPath: /opt/netbox/netbox/scripts
              subPath: {{ .Values.scriptsPersistence.subPath | default "" | quote }}
              readOnly: {{ .Values.housekeeping.readOnlyPersistence | default false }}
            {{- end }}
            {{- if .Values.housekeeping.extraVolumeMounts }}
            {{- include "common.tplvalues.render" (dict "value" .Values.housekeeping.extraVolumeMounts "context" $) | nindent 12 }}
            {{- end }}
            {{- if .Values.housekeeping.resources }}
            resources: {{ toYaml .Values.housekeeping.resources | nindent 14 }}
            {{- else if ne .Values.housekeeping.resourcesPreset "none" }}
            resources: {{- include "common.resources.preset" (dict "type" .Values.housekeeping.resourcesPreset) | nindent 14 }}
            {{- end }}
          {{- if .Values.housekeeping.sidecars }}
          {{- include "common.tplvalues.render" (dict "value" .Values.housekeeping.sidecars "context" $) | nindent 10 }}
          {{- end }}
          volumes:
          - name: config
            configMap:
              name: {{ include "common.names.fullname" . }}
          - name: secrets
            projected:
              sources:
              - secret:
                  name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "defaultNameSuffix" "config" "context" $) }}
                  items:
                  - key: secret_key
                    path: secret_key
                  {{- if has "netbox.authentication.LDAPBackend" .Values.remoteAuth.backends }}
                  - key: ldap_bind_password
                    path: ldap_bind_password
                  {{- end }}
              - secret:
                  name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "defaultNameSuffix" "config" "context" $) }}
                  optional: true
                  items:
                  - key: api_token_peppers
                    path: api_token_peppers
              - secret:
                  name: {{ include "common.secrets.name" (dict "existingSecret" (default .Values.existingSecret .Values.email.existingSecretName) "defaultNameSuffix" "config" "context" $) }}
                  items:
                  - key: {{ include "netbox.email.secretKey" . | quote }}
                    path: email_password
              - secret:
                  name: {{ include "netbox.postgresql.secret" . | quote }}
                  items:
                  - key: {{ include "netbox.postgresql.secretKey" . | quote }}
                    path: db_password
              - secret:
                  name: {{ include "netbox.tasksDatabase.secret" . | quote }}
                  items:
                  - key: {{ include "netbox.tasksDatabase.secretKey" . | quote }}
                    path: tasks_password
              - secret:
                  name: {{ include "netbox.cachingDatabase.secret" . | quote }}
                  items:
                  - key: {{ include "netbox.cachingDatabase.secretKey" . | quote }}
                    path: cache_password
          {{- include "netbox.extraConfig.volumes" . | nindent 10 }}
          - name: netbox-tmp
            emptyDir:
              medium: Memory
          - name: media
            {{- if .Values.persistence.enabled }}
            persistentVolumeClaim:
              claimName: {{ .Values.persistence.existingClaim | default (printf "%s-media" (include "common.names.fullname" .)) }}
              readOnly: {{ .Values.housekeeping.readOnlyPersistence | default false }}
            {{- else }}
            emptyDir: {}
            {{- end }}
          {{- if .Values.reportsPersistence.enabled }}
          - name: reports
            persistentVolumeClaim:
              claimName: {{ .Values.reportsPersistence.existingClaim | default (printf "%s-reports" (include "common.names.fullname" .)) }}
              readOnly: {{ .Values.housekeeping.readOnlyPersistence | default false }}
          {{- end }}
          {{- if .Values.scriptsPersistence.enabled }}
          - name: scripts
            persistentVolumeClaim:
              claimName: {{ .Values.scriptsPersistence.existingClaim | default (printf "%s-scripts" (include "common.names.fullname" .)) }}
              readOnly: {{ .Values.housekeeping.readOnlyPersistence | default false }}
          {{- end }}
          {{- if .Values.housekeeping.extraVolumes }}
          {{- include "common.tplvalues.render" (dict "value" .Values.housekeeping.extraVolumes "context" $) | nindent 10 }}
          {{- end }}
          {{- if .Values.housekeeping.nodeSelector }}
          nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.housekeeping.nodeSelector "context" $) | nindent 12 }}
          {{- end }}
          {{- if .Values.housekeeping.affinity }}
          affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.housekeeping.affinity "context" $) | nindent 12 }}
          {{- end }}
          {{- if .Values.housekeeping.tolerations }}
          tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.housekeeping.tolerations "context" .) | nindent 12 }}
          {{- end }}
          restartPolicy: {{ .Values.housekeeping.restartPolicy }}
{{- end -}}


================================================
FILE: charts/netbox/templates/deployment.yaml
================================================
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "common.names.fullname" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
    app.kubernetes.io/component: netbox
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
  selector:
    matchLabels: {{- include "common.labels.matchLabels" (dict "customLabels" .Values.podLabels "context" $) | nindent 6 }}
      app.kubernetes.io/component: netbox
  {{- if .Values.updateStrategy }}
  strategy: {{- include "common.tplvalues.render" (dict "value" .Values.updateStrategy "context" $) | nindent 4 }}
  {{- end }}
  template:
    metadata:
      annotations:
        {{- if .Values.podAnnotations }}
        {{- include "common.tplvalues.render" ( dict "value" .Values.podAnnotations "context" $ ) | nindent 8 }}
        {{- end }}
        checksum/config: {{ include "common.utils.checksumTemplate" (dict "path" "/configmap.yaml" "context" $) }}
        {{- if (not .Values.existingSecret) }}
        checksum/secret: {{ include "common.utils.checksumTemplate" (dict "path" "/secret.yaml" "context" $) }}
        {{- end }}
      labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.podLabels "context" $ ) | nindent 8 }}
        app.kubernetes.io/component: netbox
    spec:
      {{- include "common.images.renderPullSecrets" (dict "images" (list .Values.image) "context" $) | nindent 6 }}
      serviceAccountName: {{ include "netbox.serviceAccountName" . }}
      automountServiceAccountToken: {{ .Values.automountServiceAccountToken }}
      {{- if .Values.podSecurityContext.enabled }}
      securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.podSecurityContext "context" $) | nindent 8 }}
      {{- end }}
      initContainers:
      - name: init-dirs
        image: {{ include "netbox.init.image" . | quote }}
        imagePullPolicy: {{ .Values.init.image.pullPolicy | quote }}
        command: [/bin/sh, -c, mkdir -p /opt/unit/state /opt/unit/tmp]
        {{- if .Values.init.resources }}
        resources: {{- toYaml .Values.init.resources | nindent 11 }}
        {{- else if ne .Values.init.resourcesPreset "none" }}
        resources: {{- include "common.resources.preset" (dict "type" .Values.init.resourcesPreset) | nindent 10 }}
        {{- end }}
        {{- if .Values.init.securityContext.enabled }}
        securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.init.securityContext "context" $) | nindent 10 }}
        {{- end }}
        volumeMounts:
        - name: optunit
          mountPath: /opt/unit
      {{- if .Values.initContainers }}
      {{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | trim | nindent 6 }}
      {{- end }}
      containers:
      - name: {{ .Chart.Name }}
        {{- if .Values.securityContext.enabled }}
        securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.securityContext "context" $) | nindent 10 }}
        {{- end }}
        image: {{ include "netbox.image" . | quote }}
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        {{- if .Values.command }}
        command: {{- include "common.tplvalues.render" (dict "value" .Values.command "context" $) | nindent 10 }}
        {{- end }}
        {{- if .Values.args }}
        args: {{- include "common.tplvalues.render" (dict "value" .Values.args "context" $) | nindent 10 }}
        {{- end }}
        env:
        - name: SUPERUSER_NAME
          valueFrom:
            secretKeyRef:
              name: {{ include "common.secrets.name" (dict "existingSecret" .Values.superuser.existingSecret "defaultNameSuffix" "superuser" "context" $) }}
              key: username
        - name: SUPERUSER_EMAIL
          valueFrom:
            secretKeyRef:
              name: {{ include "common.secrets.name" (dict "existingSecret" .Values.superuser.existingSecret "defaultNameSuffix" "superuser" "context" $) }}
              key: email
        {{- if and .Values.metrics.enabled .Values.metrics.granian.enabled }}
        - name: GRANIAN_METRICS_ENABLED
          value: {{ .Values.metrics.granian.enabled | quote }}
        {{- if and .Values.metrics.granian.serviceMonitor.enabled .Values.metrics.granian.serviceMonitor.interval }}
        - name: GRANIAN_METRICS_SCRAPE_INTERVAL
          value: {{ .Values.metrics.granian.serviceMonitor.interval | quote }}
        {{- end }}
        {{- end }}
        {{- if .Values.dbWaitDebug }}
        - name: DB_WAIT_DEBUG
          value: "1"
        {{- end }}
        {{- if .Values.allowedHostsIncludesPodIP }}
        - name: POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP
        {{- end }}
        {{- if .Values.extraEnvs }}
        {{- include "common.tplvalues.render" (dict "value" .Values.extraEnvs "context" $) | nindent 8 }}
        {{- end }}
        {{- if or .Values.extraEnvVarsCM .Values.extraEnvVarsSecret }}
        envFrom:
          {{- if .Values.extraEnvVarsCM }}
          - configMapRef:
              name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsCM "context" $) }}
          {{- end }}
          {{- if .Values.extraEnvVarsSecret }}
          - secretRef:
              name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsSecret "context" $) }}
          {{- end }}
        {{- end }}
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        {{- if .Values.metrics.granian.serviceMonitor.enabled}}
        - name: granian-metrics
          containerPort: 9090
          protocol: TCP
        {{- end }}
        {{- if .Values.customLivenessProbe }}
        livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 10 }}
        {{- else if .Values.livenessProbe.enabled }}
        livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.livenessProbe "enabled") "context" $) | nindent 10 }}
          tcpSocket:
            port: http
        {{- end }}
        {{- if .Values.customReadinessProbe }}
        readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 10 }}
        {{- else if .Values.readinessProbe.enabled }}
        readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.readinessProbe "enabled") "context" $) | nindent 10 }}
          httpGet:
            path: /{{ .Values.basePath }}login/
            port: http
            {{- if (not (eq (index .Values.allowedHosts 0) "*")) }}
            httpHeaders:
            - name: Host
              value: {{ (index .Values.allowedHosts 0) | quote }}
            {{- end }}
        {{- end }}
        {{- if .Values.customStartupProbe }}
        startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customStartupProbe "context" $) | nindent 10 }}
        {{- else if .Values.startupProbe.enabled }}
        startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.startupProbe "enabled") "context" $) | nindent 10 }}
          httpGet:
            path: /{{ .Values.basePath }}login/
            port: http
            {{- if (not (eq (index .Values.allowedHosts 0) "*")) }}
            httpHeaders:
            - name: Host
              value: {{ (index .Values.allowedHosts 0) | quote }}
            {{- end }}
        {{- end }}
        {{- if .Values.lifecycleHooks }}
        lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.lifecycleHooks "context" $) | nindent 10 }}
        {{- end }}
        volumeMounts:
        - name: config
          mountPath: /etc/netbox/config/configuration.py
          subPath: configuration.py
          readOnly: true
        {{- if has "netbox.authentication.LDAPBackend" .Values.remoteAuth.backends }}
        - name: config
          mountPath: /etc/netbox/config/ldap/ldap_config.py
          subPath: ldap_config.py
          readOnly: true
        {{- if .Values.remoteAuth.ldap.caCertData }}
        - name: config
          mountPath: /etc/netbox/config/ldap/ldap_ca.crt
          subPath: ldap_ca.crt
          readOnly: true
        {{- end }}
        {{- end }}
        - name: config
          mountPath: /run/config/netbox
          readOnly: true
        - name: secrets
          mountPath: /run/secrets/netbox
          readOnly: true
        {{- include "netbox.extraConfig.volumeMounts" . | nindent 8 }}
        - name: netbox-tmp
          mountPath: /tmp
        - name: media
          mountPath: /opt/netbox/netbox/media
          subPath: {{ .Values.persistence.subPath | default "" | quote }}
        {{- if .Values.reportsPersistence.enabled }}
        - name: reports
          mountPath: /opt/netbox/netbox/reports
          subPath: {{ .Values.reportsPersistence.subPath | default "" | quote }}
        {{- end }}
        {{- if .Values.scriptsPersistence.enabled }}
        - name: scripts
          mountPath: /opt/netbox/netbox/scripts
          subPath: {{ .Values.scriptsPersistence.subPath | default "" | quote }}
        {{- end }}
        - name: optunit
          mountPath: /opt/unit
        - name: secrets
          mountPath: /run/secrets/superuser_password
          subPath: superuser_password
          readOnly: true
        - name: secrets
          mountPath: /run/secrets/superuser_api_token
          subPath: superuser_api_token
          readOnly: true
        {{- if .Values.extraVolumeMounts }}
        {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumeMounts "context" $) | nindent 8 }}
        {{- end }}
        {{- if .Values.resources }}
        resources: {{- toYaml .Values.resources | nindent 10 }}
        {{- else if ne .Values.resourcesPreset "none" }}
        resources: {{- include "common.resources.preset" (dict "type" .Values.resourcesPreset) | nindent 10 }}
        {{- end }}
      {{- if .Values.sidecars }}
      {{- include "common.tplvalues.render" (dict "value" .Values.sidecars "context" $) | nindent 6 }}
      {{- end }}
      volumes:
      - name: config
        configMap:
          name: {{ include "common.names.fullname" . }}
      - name: secrets
        projected:
          sources:
          - secret:
              name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "defaultNameSuffix" "config" "context" $) }}
              items:
              - key: secret_key
                path: secret_key
              {{- if has "netbox.authentication.LDAPBackend" .Values.remoteAuth.backends }}
              - key: ldap_bind_password
                path: ldap_bind_password
              {{- end }}
          - secret:
              name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "defaultNameSuffix" "config" "context" $) }}
              optional: true
              items:
              - key: api_token_peppers
                path: api_token_peppers
          - secret:
              name: {{ include "common.secrets.name" (dict "existingSecret" (default .Values.existingSecret .Values.email.existingSecretName) "defaultNameSuffix" "config" "context" $) }}
              items:
              - key: {{ include "netbox.email.secretKey" . | quote }}
                path: email_password
          - secret:
              name: {{ include "common.secrets.name" (dict "existingSecret" .Values.superuser.existingSecret "defaultNameSuffix" "superuser" "context" $) }}
              items:
              - key: password
                path: superuser_password
              - key: api_token
                path: superuser_api_token
          - secret:
              name: {{ include "netbox.postgresql.secret" . | quote }}
              items:
              - key: {{ include "netbox.postgresql.secretKey" . | quote }}
                path: db_password
          - secret:
              name: {{ include "netbox.tasksDatabase.secret" . | quote }}
              items:
              - key: {{ include "netbox.tasksDatabase.secretKey" . | quote }}
                path: tasks_password
          - secret:
              name: {{ include "netbox.cachingDatabase.secret" . | quote }}
              items:
              - key: {{ include "netbox.cachingDatabase.secretKey" . | quote }}
                path: cache_password
      {{- include "netbox.extraConfig.volumes" . | nindent 6 }}
      - name: netbox-tmp
        emptyDir:
          medium: Memory
      - name: optunit
        emptyDir:
          medium: Memory
      - name: media
        {{- if .Values.persistence.enabled }}
        persistentVolumeClaim:
          claimName: {{ .Values.persistence.existingClaim | default (printf "%s-media" (include "common.names.fullname" .)) }}
        {{- else }}
        emptyDir: {}
        {{- end }}
      {{- if .Values.reportsPersistence.enabled }}
      - name: reports
        persistentVolumeClaim:
          claimName: {{ .Values.reportsPersistence.existingClaim | default (printf "%s-reports" (include "common.names.fullname" .)) }}
      {{- end }}
      {{- if .Values.scriptsPersistence.enabled }}
      - name: scripts
        persistentVolumeClaim:
          claimName: {{ .Values.scriptsPersistence.existingClaim | default (printf "%s-scripts" (include "common.names.fullname" .)) }}
      {{- end }}
      {{- if .Values.extraVolumes }}
      {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumes "context" $) | nindent 6 }}
      {{- end }}
      {{- if .Values.nodeSelector }}
      nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.nodeSelector "context" $) | nindent 8 }}
      {{- end }}
      {{- if .Values.affinity }}
      affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.affinity "context" $) | nindent 8 }}
      {{- end }}
      {{- if .Values.tolerations }}
      tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" .) | nindent 8 }}
      {{- end }}
      {{- if .Values.hostAliases }}
      hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.hostAliases "context" $) | nindent 8 }}
      {{- end }}
      {{- if .Values.priorityClassName }}
      priorityClassName: {{ .Values.priorityClassName | quote }}
      {{- end }}
      {{- if .Values.schedulerName }}
      schedulerName: {{ .Values.schedulerName | quote }}
      {{- end }}
      {{- if .Values.topologySpreadConstraints }}
      topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" .) | nindent 8 }}
      {{- end }}
      {{- if .Values.terminationGracePeriodSeconds }}
      terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
      {{- end }}


================================================
FILE: charts/netbox/templates/extra-list.yaml
================================================
{{ range .Values.extraDeploy }}
---
{{ include "common.tplvalues.render" (dict "value" . "context" $) }}
{{ end }}


================================================
FILE: charts/netbox/templates/granian-servicemonitor.yaml
================================================
{{- if and .Values.metrics.granian.enabled .Values.metrics.granian.serviceMonitor.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: {{ printf "%s-granian" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }}
  namespace: {{ include "common.names.namespace" . | quote }}
  {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.metrics.granian.serviceMonitor.additionalLabels .Values.commonLabels ) "context" . ) }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
spec:
  jobLabel: {{ include "common.names.fullname" . }}
  namespaceSelector:
    matchNames:
    - {{ include "common.names.namespace" . | quote }}
  selector:
    matchLabels:
      {{- include "common.labels.matchLabels" . | nindent 6 }}
      {{- if .Values.metrics.granian.serviceMonitor.selector }}
      {{- include "common.tplvalues.render" (dict "value" .Values.metrics.granian.serviceMonitor.selector "context" $) | nindent 6 }}
      {{- end }}
  endpoints:
  - port: granian-metrics
    path: "/metrics"
    {{- if .Values.metrics.granian.serviceMonitor.interval }}
    interval: {{ .Values.metrics.granian.serviceMonitor.interval }}
    {{- end }}
    {{- if .Values.metrics.granian.serviceMonitor.scrapeTimeout }}
    scrapeTimeout: {{ .Values.metrics.granian.serviceMonitor.scrapeTimeout }}
    {{- end }}
    {{- if .Values.metrics.granian.serviceMonitor.honorLabels }}
    honorLabels: {{ .Values.metrics.granian.serviceMonitor.honorLabels }}
    {{- end }}
    {{- if .Values.metrics.granian.serviceMonitor.metricRelabelings }}
    metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.granian.serviceMonitor.metricRelabelings "context" $) | nindent 6 }}
    {{- end }}
    {{- if .Values.metrics.granian.serviceMonitor.relabelings }}
    relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.granian.serviceMonitor.relabelings "context" $) | nindent 6 }}
    {{- end }}
{{- end }}


================================================
FILE: charts/netbox/templates/hpa.yaml
================================================
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: {{ include "common.names.fullname" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
    app.kubernetes.io/component: netbox
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: {{ include "common.names.fullname" . }}
  minReplicas: {{ .Values.autoscaling.minReplicas }}
  maxReplicas: {{ .Values.autoscaling.maxReplicas }}
  {{- if .Values.autoscaling.behavior }}
  behavior:
    {{- if .Values.autoscaling.behavior.scaleUp }}
    scaleUp:
      {{- if .Values.autoscaling.behavior.scaleUp.stabilizationWindowSeconds }}
      stabilizationWindowSeconds: {{ .Values.autoscaling.behavior.scaleUp.stabilizationWindowSeconds }}
      {{- end }}
      {{- if .Values.autoscaling.behavior.scaleUp.selectPolicy }}
      selectPolicy: {{ .Values.autoscaling.behavior.scaleUp.selectPolicy | quote }}
      {{- end }}
      {{- if .Values.autoscaling.behavior.scaleUp.policies }}
      policies:
        {{- range .Values.autoscaling.behavior.scaleUp.policies }}
        - type: {{ .type | quote }}
          value: {{ .value }}
          periodSeconds: {{ .periodSeconds }}
        {{- end }}
      {{- end }}
    {{- end }}
    {{- if .Values.autoscaling.behavior.scaleDown }}
    scaleDown:
      {{- if .Values.autoscaling.behavior.scaleDown.stabilizationWindowSeconds }}
      stabilizationWindowSeconds: {{ .Values.autoscaling.behavior.scaleDown.stabilizationWindowSeconds }}
      {{- end }}
      {{- if .Values.autoscaling.behavior.scaleDown.selectPolicy }}
      selectPolicy: {{ .Values.autoscaling.behavior.scaleDown.selectPolicy | quote }}
      {{- end }}
      {{- if .Values.autoscaling.behavior.scaleDown.policies }}
      policies:
        {{- range .Values.autoscaling.behavior.scaleDown.policies }}
        - type: {{ .type | quote }}
          value: {{ .value }}
          periodSeconds: {{ .periodSeconds }}
        {{- end }}
      {{- end }}
    {{- end }}
  {{- end }}
  metrics:
  {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
  {{- end }}
  {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
  {{- end }}
{{- end }}


================================================
FILE: charts/netbox/templates/httproute.yaml
================================================
{{- if .Values.httpRoute.enabled -}}
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: {{ include "common.names.fullname" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if or .Values.httpRoute.annotations .Values.commonAnnotations }}
  {{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.httpRoute.annotations .Values.commonAnnotations) "context" .) }}
  annotations:
    {{- include "common.tplvalues.render" (dict "value" $annotations "context" $) | nindent 4 }}
  {{- end }}
spec:
  {{- with .Values.httpRoute.parentRefs }}
  parentRefs:
    {{- toYaml . | nindent 4 }}
  {{- end }}
  {{- with .Values.httpRoute.hostnames }}
  hostnames:
    {{- toYaml . | nindent 4 }}
  {{- end }}
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      {{- with .Values.httpRoute.filters }}
      filters:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      backendRefs:
        - name: {{ include "common.names.fullname" . }}
          port: {{ .Values.service.port }}
{{- end }}


================================================
FILE: charts/netbox/templates/ingress.yaml
================================================
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ include "common.names.fullname" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if or .Values.ingress.annotations .Values.commonAnnotations }}
  {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.ingress.annotations .Values.commonAnnotations ) "context" . ) }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
  {{- end }}
spec:
  {{- if .Values.ingress.className }}
  ingressClassName: {{ .Values.ingress.className | quote }}
  {{- end }}
  {{- with .Values.ingress.tls }}
  tls:
  {{- range . }}
  - hosts:
    {{- range .hosts }}
    - {{ . | quote }}
    {{- end }}
    secretName: {{ .secretName }}
  {{- end }}
  {{- end }}
  rules:
  {{- range .Values.ingress.hosts }}
  - host: {{ .host | quote }}
    http:
      paths:
      {{- range .paths }}
      {{- if kindIs "string" . }}
      - path: {{ . }}
        pathType: Prefix
        backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" $) "servicePort" "http" "context" $) | nindent 10 }}
      {{- else }}
      {{- (list .) | toYaml | nindent 6 }}
      {{- end }}
      {{- end }}
  {{- end }}
{{- end }}


================================================
FILE: charts/netbox/templates/pdb.yaml
================================================
{{- if and .Values.pdb.enabled (or .Values.pdb.minAvailable .Values.pdb.maxUnavailable) }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: {{ include "common.names.fullname" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
    app.kubernetes.io/component: netbox
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
spec:
  selector:
    matchLabels: {{- include "common.labels.matchLabels" (dict "customLabels" .Values.podLabels "context" $) | nindent 6 }}
      app.kubernetes.io/component: netbox
  {{- if .Values.pdb.minAvailable }}
  minAvailable: {{ .Values.pdb.minAvailable }}
  {{- end }}
  {{- if .Values.pdb.maxUnavailable }}
  maxUnavailable: {{ .Values.pdb.maxUnavailable }}
  {{- end }}
{{- end }}


================================================
FILE: charts/netbox/templates/pvc.yaml
================================================
{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: {{ printf "%s-media" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if or .Values.persistence.annotations .Values.commonAnnotations }}
  {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.persistence.annotations .Values.commonAnnotations ) "context" . ) }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
  {{- end }}
spec:
  accessModes:
  - {{ .Values.persistence.accessMode | quote }}
  resources:
    requests:
      storage: {{ .Values.persistence.size | quote }}
  {{- if .Values.persistence.selector }}
  selector: {{- include "common.tplvalues.render" (dict "value" .Values.persistence.selector "context" $) | nindent 4 }}
  {{- end }}
  {{- include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) | nindent 2 }}
{{- end }}
{{- if and .Values.reportsPersistence.enabled (not .Values.reportsPersistence.existingClaim) }}
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: {{ printf "%s-reports" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if or .Values.reportsPersistence.annotations .Values.commonAnnotations }}
  {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.reportsPersistence.annotations .Values.commonAnnotations ) "context" . ) }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
  {{- end }}
spec:
  accessModes:
    - {{ .Values.reportsPersistence.accessMode | quote }}
  resources:
    requests:
      storage: {{ .Values.reportsPersistence.size | quote }}
  {{- if .Values.reportsPersistence.selector }}
  selector: {{- include "common.tplvalues.render" (dict "value" .Values.reportsPersistence.selector "context" $) | nindent 4 }}
  {{- end }}
  {{- include "common.storage.class" (dict "persistence" .Values.reportsPersistence "global" .Values.global) | nindent 2 }}
{{- end }}
{{- if and .Values.scriptsPersistence.enabled (not .Values.scriptsPersistence.existingClaim) }}
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: {{ printf "%s-scripts" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if or .Values.scriptsPersistence.annotations .Values.commonAnnotations }}
  {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.scriptsPersistence.annotations .Values.commonAnnotations ) "context" . ) }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
  {{- end }}
spec:
  accessModes:
    - {{ .Values.scriptsPersistence.accessMode | quote }}
  resources:
    requests:
      storage: {{ .Values.scriptsPersistence.size | quote }}
  {{- if .Values.scriptsPersistence.selector }}
  selector: {{- include "common.tplvalues.render" (dict "value" .Values.scriptsPersistence.selector "context" $) | nindent 4 }}
  {{- end }}
  {{- include "common.storage.class" (dict "persistence" .Values.scriptsPersistence "global" .Values.global) | nindent 2 }}
{{- end }}


================================================
FILE: charts/netbox/templates/role.yaml
================================================
{{- if .Values.rbac.create }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: {{ include "common.names.fullname" . }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  namespace: {{ include "common.names.namespace" . | quote }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
rules:
  {{- if and .Values.worker.enabled .Values.worker.waitForBackend.enabled }}
  - apiGroups:
      - apps
    resources:
      - statefulsets
      - deployments
      - replicasets
    verbs:
      - get
      - list
      - watch
  {{- end }}
  {{- if .Values.rbac.rules }}
  {{- include "common.tplvalues.render" ( dict "value" .Values.rbac.rules "context" $ ) | nindent 2 }}
  {{- end }}
{{- end }}


================================================
FILE: charts/netbox/templates/rolebinding.yaml
================================================
{{- if .Values.rbac.create }}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: {{ include "common.names.fullname" . }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  namespace: {{ include "common.names.namespace" . | quote }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
roleRef:
  kind: Role
  name: {{ include "common.names.fullname" . }}
  apiGroup: rbac.authorization.k8s.io
subjects:
  - kind: ServiceAccount
    name: {{ include "netbox.serviceAccountName" . }}
    namespace: {{ include "common.names.namespace" . | quote }}
{{- end }}


================================================
FILE: charts/netbox/templates/secret.yaml
================================================
{{- if not .Values.existingSecret }}
---
apiVersion: v1
kind: Secret
metadata:
  name: {{ include "common.secrets.name" (dict "defaultNameSuffix" "config" "context" $) }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
type: Opaque
data:
  {{- if not .Values.email.existingSecretName }}
  email_password: {{ .Values.email.password | b64enc | quote }}
  {{- end }}
  secret_key: {{ include "common.secrets.passwords.manage" (dict "secret" (include "common.secrets.name" (dict "defaultNameSuffix" "config" "context" $)) "key" "secret_key" "providedValues" (list "secretKey") "length" 60 "strong" true "failOnNew" false "context" $) }}
  api_token_peppers: {{ include "netbox.apiTokenPeppers.secret" . }}
  {{- if has "netbox.authentication.LDAPBackend" .Values.remoteAuth.backends }}
  ldap_bind_password: {{ .Values.remoteAuth.ldap.bindPassword | b64enc | quote }}
  {{- end }}
{{- end }}
{{- if not .Values.superuser.existingSecret }}
---
apiVersion: v1
kind: Secret
metadata:
  name: {{ include "common.secrets.name" (dict "defaultNameSuffix" "superuser" "context" $) }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
type: kubernetes.io/basic-auth
data:
  username: {{ .Values.superuser.name | default "admin" | b64enc | quote }}
  password: {{ include "common.secrets.passwords.manage" (dict "secret" (include "common.secrets.name" (dict "defaultNameSuffix" "superuser" "context" $)) "key" "password" "providedValues" (list "superuser.password") "context" $) }}
  email: {{ .Values.superuser.email | b64enc | quote }}
  api_token: {{ .Values.superuser.apiToken | default uuidv4 | b64enc | quote }}
{{- end }}
{{- if not (or .Values.postgresql.enabled .Values.externalDatabase.existingSecretName) }}
---
apiVersion: v1
kind: Secret
metadata:
  name: {{ include "common.secrets.name" (dict "defaultNameSuffix" "postgresql" "context" $) }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
type: Opaque
data:
  db_password: {{ .Values.externalDatabase.password | b64enc | quote }}
{{- end }}
{{- if not (or .Values.valkey.enabled (and .Values.tasksDatabase.existingSecretName .Values.cachingDatabase.existingSecretName)) }}
---
apiVersion: v1
kind: Secret
metadata:
  name: {{ include "common.secrets.name" (dict "defaultNameSuffix" "kv" "context" $) }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
type: Opaque
data:
  {{- if not .Values.tasksDatabase.existingSecretName }}
  tasks_password: {{ .Values.tasksDatabase.password | b64enc | quote }}
  {{- end }}
  {{- if not .Values.cachingDatabase.existingSecretName }}
  cache_password: {{ .Values.cachingDatabase.password | b64enc | quote }}
  {{- end }}
{{- end }}


================================================
FILE: charts/netbox/templates/service.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  name: {{ include "common.names.fullname" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if or .Values.service.annotations .Values.commonAnnotations }}
  {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.service.annotations .Values.commonAnnotations ) "context" . ) }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
  {{- end }}
spec:
  type: {{ .Values.service.type }}
  ports:
  - port: {{ .Values.service.port }}
    targetPort: http
    protocol: TCP
    name: http
    {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePort)) }}
    nodePort: {{ .Values.service.nodePort }}
    {{- else if eq .Values.service.type "ClusterIP" }}
    nodePort: null
    {{- end }}
  {{- if and .Values.metrics.enabled .Values.metrics.granian.enabled }}
  - port: 9090
    targetPort: granian-metrics
    protocol: TCP
    name: granian-metrics
    {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePort)) }}
    nodePort: {{ .Values.service.nodePort }}
    {{- else if eq .Values.service.type "ClusterIP" }}
    nodePort: null
    {{- end }}
  {{- end }}
  selector:
    {{- include "common.labels.matchLabels" . | nindent 4 }}
    app.kubernetes.io/component: netbox
  {{- if and .Values.service.clusterIP (eq .Values.service.type "ClusterIP") }}
  clusterIP: {{ .Values.service.clusterIP }}
  {{- end }}
  {{- if and .Values.service.clusterIPs (eq .Values.service.type "ClusterIP") }}
  clusterIPs: {{- include "common.tplvalues.render" (dict "value" .Values.service.clusterIPs "context" $) | nindent 4 }}
  {{- end }}
  {{- if .Values.service.externalIPs }}
  clusterIPs: {{- include "common.tplvalues.render" (dict "value" .Values.service.externalIPs "context" $) | nindent 4 }}
  {{- end }}
  {{- if .Values.service.sessionAffinity }}
  sessionAffinity: {{ .Values.service.sessionAffinity }}
  {{- end }}
  {{- if .Values.service.sessionAffinityConfig }}
  sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.service.sessionAffinityConfig "context" $) | nindent 4 }}
  {{- end }}
  {{- if .Values.service.ipFamilyPolicy }}
  ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy | quote }}
  {{- end }}
  {{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }}
  externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }}
  {{- end }}
  {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerSourceRanges)) }}
  loadBalancerSourceRanges: {{ .Values.service.loadBalancerSourceRanges }}
  {{- end }}
  {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }}
  loadBalancerIP: {{ .Values.service.loadBalancerIP }}
  {{- end }}
  {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerClass)) }}
  loadBalancerClass: {{ .Values.service.loadBalancerClass | quote }}
  {{- end }}


================================================
FILE: charts/netbox/templates/serviceaccount.yaml
================================================
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
metadata:
  name: {{ include "netbox.serviceAccountName" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  {{- if or .Values.commonAnnotations .Values.serviceAccount.annotations }}
  {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.serviceAccount.annotations .Values.commonAnnotations ) "context" . ) }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
  {{- end }}
{{- end }}


================================================
FILE: charts/netbox/templates/servicemonitor.yaml
================================================
{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: {{ include "common.names.fullname" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.metrics.serviceMonitor.additionalLabels .Values.commonLabels ) "context" . ) }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
spec:
  jobLabel: {{ include "common.names.fullname" . }}
  namespaceSelector:
    matchNames:
    - {{ include "common.names.namespace" . | quote }}
  selector:
    matchLabels:
      {{- include "common.labels.matchLabels" . | nindent 6 }}
      {{- if .Values.metrics.serviceMonitor.selector }}
      {{- include "common.tplvalues.render" (dict "value" .Values.metrics.serviceMonitor.selector "context" $) | nindent 6 }}
      {{- end }}
  endpoints:
  - port: http
    path: "/metrics"
    {{- if .Values.metrics.serviceMonitor.interval }}
    interval: {{ .Values.metrics.serviceMonitor.interval }}
    {{- end }}
    {{- if .Values.metrics.serviceMonitor.scrapeTimeout }}
    scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }}
    {{- end }}
    {{- if .Values.metrics.serviceMonitor.honorLabels }}
    honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }}
    {{- end }}
    {{- if .Values.metrics.serviceMonitor.metricRelabelings }}
    metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 6 }}
    {{- end }}
    {{- if .Values.metrics.serviceMonitor.relabelings }}
    relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.relabelings "context" $) | nindent 6 }}
    {{- end }}
{{- end }}


================================================
FILE: charts/netbox/templates/tests/test-connection.yaml
================================================
apiVersion: v1
kind: Pod
metadata:
  name: {{ printf "%s-test-connection" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }}
  labels:
    {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
  annotations:
    "helm.sh/hook": test
    {{- if .Values.commonAnnotations }}
    {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
    {{- end }}
spec:
  containers:
  - name: wget
    image: "{{ .Values.test.image.repository }}:{{ .Values.test.image.tag }}"
    imagePullPolicy: {{ .Values.test.image.pullPolicy }}
    command: ['wget']
    args: ['{{ include "common.names.fullname" . }}:{{ .Values.service.port }}']
    {{- if .Values.test.resources }}
    resources: {{ toYaml .Values.test.resources | nindent 6 }}
    {{- else if ne .Values.test.resourcesPreset "none" }}
    resources: {{- include "common.resources.preset" (dict "type" .Values.test.resourcesPreset) | nindent 6 }}
    {{- end }}
    {{- if .Values.test.securityContext.enabled }}
    securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.test.securityContext "context" $) | nindent 6 }}
    {{- end }}
  restartPolicy: Never


================================================
FILE: charts/netbox/templates/worker/deployment.yaml
================================================
{{- if .Values.worker.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ printf "%s-worker" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
    app.kubernetes.io/component: worker
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
spec:
  {{- if not .Values.worker.autoscaling.enabled }}
  replicas: {{ .Values.worker.replicaCount }}
  {{- end }}
  revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
  selector:
    matchLabels: {{- include "common.labels.matchLabels" (dict "customLabels" .Values.worker.podLabels "context" $) | nindent 6 }}
      app.kubernetes.io/component: worker
  {{- if .Values.worker.updateStrategy }}
  strategy: {{- include "common.tplvalues.render" (dict "value" .Values.worker.updateStrategy "context" $) | nindent 4 }}
  {{- end }}
  template:
    metadata:
      annotations:
        {{- if .Values.worker.podAnnotations }}
        {{- include "common.tplvalues.render" ( dict "value" .Values.worker.podAnnotations "context" $ ) | nindent 8 }}
        {{- end }}
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
        {{- if (not .Values.existingSecret) }}
        checksum/secr
Download .txt
gitextract_jmg13inm/

├── .checkov.yaml
├── .editorconfig
├── .flake8
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   └── feature_request.yml
│   ├── dependabot.yml
│   ├── renovate.json
│   └── workflows/
│       ├── analysis.yml
│       ├── auto-merge.yml
│       ├── ci.yml
│       ├── lint.yml
│       ├── release.yml
│       └── test.yml
├── .gitignore
├── .markdownlint.yaml
├── LICENSE
├── README.md
├── charts/
│   ├── netbox/
│   │   ├── .helmignore
│   │   ├── Chart.yaml
│   │   ├── README.md
│   │   ├── ci/
│   │   │   ├── default-values.yaml
│   │   │   ├── ingress-metrics-values.yaml
│   │   │   └── ldap-values.yaml
│   │   ├── docs/
│   │   │   ├── auth.md
│   │   │   ├── extra.md
│   │   │   ├── migrate.md
│   │   │   └── prod.md
│   │   ├── files/
│   │   │   ├── configuration.py
│   │   │   └── ldap_config.py
│   │   ├── templates/
│   │   │   ├── NOTES.txt
│   │   │   ├── _helpers.tpl
│   │   │   ├── configmap.yaml
│   │   │   ├── cronjob.yaml
│   │   │   ├── deployment.yaml
│   │   │   ├── extra-list.yaml
│   │   │   ├── granian-servicemonitor.yaml
│   │   │   ├── hpa.yaml
│   │   │   ├── httproute.yaml
│   │   │   ├── ingress.yaml
│   │   │   ├── pdb.yaml
│   │   │   ├── pvc.yaml
│   │   │   ├── role.yaml
│   │   │   ├── rolebinding.yaml
│   │   │   ├── secret.yaml
│   │   │   ├── service.yaml
│   │   │   ├── serviceaccount.yaml
│   │   │   ├── servicemonitor.yaml
│   │   │   ├── tests/
│   │   │   │   └── test-connection.yaml
│   │   │   └── worker/
│   │   │       ├── deployment.yaml
│   │   │       ├── hpa.yaml
│   │   │       └── pdb.yaml
│   │   ├── values.schema.json
│   │   └── values.yaml
│   └── netbox-operator/
│       ├── .helmignore
│       ├── Chart.yaml
│       ├── README.md
│       ├── ci/
│       │   └── default-values.yaml
│       ├── crds/
│       │   ├── ipaddressclaims.yaml
│       │   ├── ipaddresses.yaml
│       │   ├── iprangeclaims.yaml
│       │   ├── ipranges.yaml
│       │   ├── prefixclaims.yaml
│       │   └── prefixes.yaml
│       ├── templates/
│       │   ├── NOTES.txt
│       │   ├── _helpers.tpl
│       │   ├── clusterrole.yaml
│       │   ├── clusterrolebinding.yaml
│       │   ├── deployment.yaml
│       │   ├── leaderelect/
│       │   │   ├── role.yaml
│       │   │   └── rolebinding.yaml
│       │   ├── secret.yaml
│       │   ├── serviceaccount.yaml
│       │   └── servicemonitor.yaml
│       └── values.yaml
├── config.yaml
└── pyproject.toml
Download .txt
SYMBOL INDEX (6 symbols across 2 files)

FILE: charts/netbox/files/configuration.py
  function _deep_merge (line 14) | def _deep_merge(source, destination):
  function _load_yaml (line 27) | def _load_yaml() -> None:
  function _read_secret (line 40) | def _read_secret(secret_name: str, secret_key: str, default: str | None ...

FILE: charts/netbox/files/ldap_config.py
  function _load_yaml (line 16) | def _load_yaml() -> None:
  function _read_secret (line 23) | def _read_secret(secret_name: str, secret_key: str, default: str | None ...
  function _import_group_type (line 37) | def _import_group_type(group_type_name: str) -> Any | None:
Condensed preview — 79 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (449K chars).
[
  {
    "path": ".checkov.yaml",
    "chars": 136,
    "preview": "directory:\n  - charts\nskip-path:\n  - /\\w+/charts\nevaluate-variables: true\nframework:\n  - helm\ncompact: true\nquiet: true\n"
  },
  {
    "path": ".editorconfig",
    "chars": 232,
    "preview": "# editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_"
  },
  {
    "path": ".flake8",
    "chars": 141,
    "preview": "[flake8]\nmax-line-length = 100\nextend-ignore = E203, W503\nper-file-ignores =\n  charts/netbox/files/*:E131,E251,E266,E302"
  },
  {
    "path": ".gitattributes",
    "chars": 263,
    "preview": "# https://git-scm.com/docs/gitattributes\n\n# Auto detect text files and perform LF normalization\n* text=auto eol=lf\n\n# Co"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 120,
    "preview": "# https://docs.github.com/articles/displaying-a-sponsor-button-in-your-repository\n\ngithub:\n  - RangerRick\n  - LeoColomb\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "chars": 2659,
    "preview": "name: 🐛 Bug Report\ndescription: Create a report about a malfunction of the Helm chart setup\nlabels:\n  - bug\nbody:\n  - ty"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 612,
    "preview": "# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yml",
    "chars": 1314,
    "preview": "name: ✨ Feature Request\ndescription: Propose a new NetBox feature or enhancement\nlabels:\n  - enhancement\nbody:\n  - type:"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 245,
    "preview": "# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabo"
  },
  {
    "path": ".github/renovate.json",
    "chars": 873,
    "preview": "{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\n    \"config:recommended\",\n    \":confi"
  },
  {
    "path": ".github/workflows/analysis.yml",
    "chars": 653,
    "preview": "# https://docs.github.com/actions\n\nname: Analysis\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    branches:\n"
  },
  {
    "path": ".github/workflows/auto-merge.yml",
    "chars": 896,
    "preview": "# https://docs.github.com/actions\n\nname: Auto-merge\n\non:\n  pull_request_target:\n  workflow_call:\n\npermissions:\n  pull-re"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 1576,
    "preview": "# yamllint disable rule:document-start\n# https://docs.github.com/actions\n\nname: CI\n\non:\n  push:\n    branches:\n      - ma"
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 1250,
    "preview": "# https://docs.github.com/actions\n\nname: Lint Code Base\n\non:\n  push:\n    branches-ignore: [main]\n  pull_request:\n    bra"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 2207,
    "preview": "# yamllint disable rule:document-start\n# https://docs.github.com/actions\n\nname: Release\n\non:\n  workflow_call:\n    secret"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 1246,
    "preview": "# yamllint disable rule:document-start\n# https://docs.github.com/actions\n\nname: Test\n\non:\n  workflow_call:\n    inputs:\n "
  },
  {
    "path": ".gitignore",
    "chars": 378,
    "preview": "# https://git-scm.com/docs/gitignore\n\n# General files\npkg/*\n*.pyc\n.project\n/.bin\n/_test/secrets/*.json\n\n# macOS\n._*\n.DS_"
  },
  {
    "path": ".markdownlint.yaml",
    "chars": 53,
    "preview": "default: true\nMD013: false\nMD031: false\nMD060: false\n"
  },
  {
    "path": "LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "README.md",
    "chars": 2522,
    "preview": "# Netbox Helm Charts\n\n> The official [Helm](https://helm.sh) charts repository for [Netbox](https://netbox.dev).\n\n[![Bui"
  },
  {
    "path": "charts/netbox/.helmignore",
    "chars": 462,
    "preview": "# Patterns to ignore when building packages.\n# This supports shell glob matching, relative path matching, and\n# negation"
  },
  {
    "path": "charts/netbox/Chart.yaml",
    "chars": 1618,
    "preview": "apiVersion: v2\nname: netbox\nversion: 8.2.7\n# renovate: image=ghcr.io/netbox-community/netbox\nappVersion: \"v4.6.0\"\ntype: "
  },
  {
    "path": "charts/netbox/README.md",
    "chars": 61792,
    "preview": "# NetBox\n\n[NetBox](https://netbox.dev) is an IP address management (IPAM) and\ndata center infrastructure management (DCI"
  },
  {
    "path": "charts/netbox/ci/default-values.yaml",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "charts/netbox/ci/ingress-metrics-values.yaml",
    "chars": 51,
    "preview": "ingress:\n  enabled: true\n\nmetrics:\n  enabled: true\n"
  },
  {
    "path": "charts/netbox/ci/ldap-values.yaml",
    "chars": 883,
    "preview": "remoteAuth:\n  enabled: true\n  backends:\n    - netbox.authentication.LDAPBackend\n\n  ldap:\n    serverUri: \"ldap://ldap.for"
  },
  {
    "path": "charts/netbox/docs/auth.md",
    "chars": 8843,
    "preview": "# Authentication Options\n\n## Using SSO\n\nYou can configure different SSO backends with `remoteAuth`.\nThe implementation i"
  },
  {
    "path": "charts/netbox/docs/extra.md",
    "chars": 2213,
    "preview": "# Extra Configuration\n\n## Overview\n\nAny additional configuration setting can be passed in the chart\nvalues to be loaded "
  },
  {
    "path": "charts/netbox/docs/migrate.md",
    "chars": 1298,
    "preview": "# Migration Guide\n\nFor major version updates (5.0.0, 6.0.0, etc.), see the release notes for detailed migration informat"
  },
  {
    "path": "charts/netbox/docs/prod.md",
    "chars": 3849,
    "preview": "# Production Considerations\n\n## Database Recommendation\n\nWe recommend using separate external PostgreSQL and Key-Value i"
  },
  {
    "path": "charts/netbox/files/configuration.py",
    "chars": 2944,
    "preview": "\"\"\"\nThis file serves as a base configuration for Netbox\nhttps://netboxlabs.com/docs/netbox/en/stable/configuration/\n\"\"\"\n"
  },
  {
    "path": "charts/netbox/files/ldap_config.py",
    "chars": 3032,
    "preview": "\"\"\"\nThis file serves as a LDAP configuration for Netbox\nhttps://netboxlabs.com/docs/netbox/en/stable/installation/6-ldap"
  },
  {
    "path": "charts/netbox/templates/NOTES.txt",
    "chars": 2566,
    "preview": "CHART NAME: {{ .Chart.Name  }}\nCHART VERSION: {{ .Chart.Version  }}\nAPP VERSION: {{ .Chart.AppVersion  }}\n\n** Please be "
  },
  {
    "path": "charts/netbox/templates/_helpers.tpl",
    "chars": 8585,
    "preview": "{{/* vim: set filetype=mustache: */}}\n\n{{/*\nReturn the proper image name\n*/}}\n{{- define \"netbox.image\" -}}\n{{- include "
  },
  {
    "path": "charts/netbox/templates/configmap.yaml",
    "chars": 12520,
    "preview": "apiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: {{ include \"common.names.fullname\" . }}\n  namespace: {{ include \"common"
  },
  {
    "path": "charts/netbox/templates/cronjob.yaml",
    "chars": 11060,
    "preview": "{{- if .Values.housekeeping.enabled -}}\napiVersion: batch/v1\nkind: CronJob\nmetadata:\n  name: {{ printf \"%s-housekeeping\""
  },
  {
    "path": "charts/netbox/templates/deployment.yaml",
    "chars": 15332,
    "preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: {{ include \"common.names.fullname\" . }}\n  namespace: {{ include \""
  },
  {
    "path": "charts/netbox/templates/extra-list.yaml",
    "chars": 115,
    "preview": "{{ range .Values.extraDeploy }}\n---\n{{ include \"common.tplvalues.render\" (dict \"value\" . \"context\" $) }}\n{{ end }}\n"
  },
  {
    "path": "charts/netbox/templates/granian-servicemonitor.yaml",
    "chars": 2233,
    "preview": "{{- if and .Values.metrics.granian.enabled .Values.metrics.granian.serviceMonitor.enabled }}\napiVersion: monitoring.core"
  },
  {
    "path": "charts/netbox/templates/hpa.yaml",
    "chars": 2866,
    "preview": "{{- if .Values.autoscaling.enabled }}\napiVersion: autoscaling/v2\nkind: HorizontalPodAutoscaler\nmetadata:\n  name: {{ incl"
  },
  {
    "path": "charts/netbox/templates/httproute.yaml",
    "chars": 1217,
    "preview": "{{- if .Values.httpRoute.enabled -}}\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: {{ inclu"
  },
  {
    "path": "charts/netbox/templates/ingress.yaml",
    "chars": 1455,
    "preview": "{{- if .Values.ingress.enabled -}}\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  name: {{ include \"common.n"
  },
  {
    "path": "charts/netbox/templates/pdb.yaml",
    "chars": 987,
    "preview": "{{- if and .Values.pdb.enabled (or .Values.pdb.minAvailable .Values.pdb.maxUnavailable) }}\napiVersion: policy/v1\nkind: P"
  },
  {
    "path": "charts/netbox/templates/pvc.yaml",
    "chars": 3794,
    "preview": "{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}\n---\nkind: PersistentVolumeClaim\napiVer"
  },
  {
    "path": "charts/netbox/templates/role.yaml",
    "chars": 904,
    "preview": "{{- if .Values.rbac.create }}\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  name: {{ include \"common.n"
  },
  {
    "path": "charts/netbox/templates/rolebinding.yaml",
    "chars": 774,
    "preview": "{{- if .Values.rbac.create }}\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: {{ include \"c"
  },
  {
    "path": "charts/netbox/templates/secret.yaml",
    "chars": 3847,
    "preview": "{{- if not .Values.existingSecret }}\n---\napiVersion: v1\nkind: Secret\nmetadata:\n  name: {{ include \"common.secrets.name\" "
  },
  {
    "path": "charts/netbox/templates/service.yaml",
    "chars": 3295,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  name: {{ include \"common.names.fullname\" . }}\n  namespace: {{ include \"common.n"
  },
  {
    "path": "charts/netbox/templates/serviceaccount.yaml",
    "chars": 775,
    "preview": "{{- if .Values.serviceAccount.create -}}\napiVersion: v1\nkind: ServiceAccount\nautomountServiceAccountToken: {{ .Values.se"
  },
  {
    "path": "charts/netbox/templates/servicemonitor.yaml",
    "chars": 2052,
    "preview": "{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }}\napiVersion: monitoring.coreos.com/v1\nkind: "
  },
  {
    "path": "charts/netbox/templates/tests/test-connection.yaml",
    "chars": 1271,
    "preview": "apiVersion: v1\nkind: Pod\nmetadata:\n  name: {{ printf \"%s-test-connection\" (include \"common.names.fullname\" .) | trunc 63"
  },
  {
    "path": "charts/netbox/templates/worker/deployment.yaml",
    "chars": 13123,
    "preview": "{{- if .Values.worker.enabled }}\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: {{ printf \"%s-worker\" (include \""
  },
  {
    "path": "charts/netbox/templates/worker/hpa.yaml",
    "chars": 3103,
    "preview": "{{- if and .Values.worker.enabled .Values.worker.autoscaling.enabled }}\napiVersion: autoscaling/v2\nkind: HorizontalPodAu"
  },
  {
    "path": "charts/netbox/templates/worker/pdb.yaml",
    "chars": 1116,
    "preview": "{{- if and .Values.worker.enabled .Values.worker.pdb.enabled (or .Values.worker.pdb.minAvailable .Values.worker.pdb.maxU"
  },
  {
    "path": "charts/netbox/values.schema.json",
    "chars": 45635,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"title\": \"Netbox Helm Chart Schema\",\n  \"type\": \"object\""
  },
  {
    "path": "charts/netbox/values.yaml",
    "chars": 75777,
    "preview": "# Default values for NetBox.\n# This is a YAML-formatted file.\n# Declare variables to be passed into your templates.\n\n## "
  },
  {
    "path": "charts/netbox-operator/.helmignore",
    "chars": 443,
    "preview": "# Patterns to ignore when building packages.\n# This supports shell glob matching, relative path matching, and\n# negation"
  },
  {
    "path": "charts/netbox-operator/Chart.yaml",
    "chars": 1242,
    "preview": "apiVersion: v2\nname: netbox-operator\nversion: 1.2.65\n# renovate: image=ghcr.io/netbox-community/netbox-operator\nappVersi"
  },
  {
    "path": "charts/netbox-operator/README.md",
    "chars": 1131,
    "preview": "# NetBox Operator\n\n[Operator](https://github.com/netbox-community/netbox-operator) to manage [NetBox](https://netbox.dev"
  },
  {
    "path": "charts/netbox-operator/ci/default-values.yaml",
    "chars": 12,
    "preview": "https: true\n"
  },
  {
    "path": "charts/netbox-operator/crds/ipaddressclaims.yaml",
    "chars": 9417,
    "preview": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuild"
  },
  {
    "path": "charts/netbox-operator/crds/ipaddresses.yaml",
    "chars": 9070,
    "preview": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuild"
  },
  {
    "path": "charts/netbox-operator/crds/iprangeclaims.yaml",
    "chars": 11105,
    "preview": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuild"
  },
  {
    "path": "charts/netbox-operator/crds/ipranges.yaml",
    "chars": 9651,
    "preview": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuild"
  },
  {
    "path": "charts/netbox-operator/crds/prefixclaims.yaml",
    "chars": 12490,
    "preview": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuild"
  },
  {
    "path": "charts/netbox-operator/crds/prefixes.yaml",
    "chars": 9601,
    "preview": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuild"
  },
  {
    "path": "charts/netbox-operator/templates/NOTES.txt",
    "chars": 103,
    "preview": "CHART NAME: {{ .Chart.Name }}\nCHART VERSION: {{ .Chart.Version }}\nAPP VERSION: {{ .Chart.AppVersion }}\n"
  },
  {
    "path": "charts/netbox-operator/templates/_helpers.tpl",
    "chars": 917,
    "preview": "{{/* vim: set filetype=mustache: */}}\n\n{{/*\nCreate the name of the service account to use\n*/}}\n{{- define \"netbox-operat"
  },
  {
    "path": "charts/netbox-operator/templates/clusterrole.yaml",
    "chars": 1318,
    "preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: {{ include \"common.names.fullname\" . }}\n  l"
  },
  {
    "path": "charts/netbox-operator/templates/clusterrolebinding.yaml",
    "chars": 694,
    "preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: {{ include \"common.names.fullname\" ."
  },
  {
    "path": "charts/netbox-operator/templates/deployment.yaml",
    "chars": 7389,
    "preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: {{ include \"common.names.fullname\" . }}\n  namespace: {{ include \""
  },
  {
    "path": "charts/netbox-operator/templates/leaderelect/role.yaml",
    "chars": 977,
    "preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  name: {{ printf \"%s-leader-election\" (include \"common.na"
  },
  {
    "path": "charts/netbox-operator/templates/leaderelect/rolebinding.yaml",
    "chars": 909,
    "preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: {{ printf \"%s-leader-election\" (include \"co"
  },
  {
    "path": "charts/netbox-operator/templates/secret.yaml",
    "chars": 648,
    "preview": "{{- if not (or .Values.netbox.enabled .Values.auth.existingSecret) }}\napiVersion: v1\nkind: Secret\nmetadata:\n  name: {{ i"
  },
  {
    "path": "charts/netbox-operator/templates/serviceaccount.yaml",
    "chars": 783,
    "preview": "{{- if .Values.serviceAccount.create }}\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: {{ include \"netbox-operato"
  },
  {
    "path": "charts/netbox-operator/templates/servicemonitor.yaml",
    "chars": 2189,
    "preview": "{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }}\napiVersion: monitoring.coreos.com/v1\nkind: "
  },
  {
    "path": "charts/netbox-operator/values.yaml",
    "chars": 15155,
    "preview": "# Default values for NetBox Operator.\n# This is a YAML-formatted file.\n# Declare variables to be passed into your templa"
  },
  {
    "path": "config.yaml",
    "chars": 292,
    "preview": "owner: netbox-community\nrepo: netbox-chart\nremote: origin\ntarget-branch: main\nsign: true\nkey: builds@netboxlabs.com\nkeyr"
  },
  {
    "path": "pyproject.toml",
    "chars": 499,
    "preview": "[tool.black]\nline_length = 100\ntarget-version = [\"py38\"]\ninclude = '\\.pyi?$'\nexclude = '''\n(\n  /(\n      \\.git\n    | \\.ve"
  }
]

About this extraction

This page contains the full source code of the bootc/netbox-chart GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 79 files (416.2 KB), approximately 96.3k tokens, and a symbol index with 6 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!